0

I have created a custom user control in my WPF application and a class that has all the properties that correspond to what I want the control to show. I am getting a collection of said class objects from a database and wish to show one custom control per object in a stackpanel-esque display.

I am aware I can get an ItemsControl, bind the collection to its items source and define a data template. What I'm NOT aware of is how to define a data template that uses my custom control and correctly binds its labels' content to the properties of the corresponding item in the collection.

Basically I have dis:

    <ItemsControl ItemsSource="{Binding ObjectsHashSet}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <customControls:myCustomControl/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>            
    </ItemsControl>

For simplycity's sake, let's say this is myCustomControl:

<UserControl [bla-bla]>
    <Label Name="lblName" Content="{Binding Name}"/>
</UserControl>

and it just shows a control with empty label. I would like to know how to tell it to bind the label's content to the "Name" property of the corresponding object in the collection for which it was created.

J. Doe
  • 99
  • 1
  • 6
  • You might have explicitly set the UserControl's DataContext, so that it does not operate on the DataContext that is provided by the item container in the ItemsControl. – Clemens Feb 02 '20 at 18:25
  • @Clemens, yes, I use an AutoViewModelLocator, which ties the user control to a ViewModel. But since the control itself actually has more advanced logic - buttons, commands and the like, I think I need it. – J. Doe Feb 02 '20 at 19:05
  • No, quite the opposite. You do not only not need it. Actually, it breaks your application logic. It is totally obvious here: your control will simply not get the DataContext provided by the framework, i.e. you have effectively disabled an essential part of the way ItemsControls are supposed to work. A UserControl should never explicitly set its own DataContext. – Clemens Feb 02 '20 at 19:28
  • @Clemens, wait, what if the user control has a button that should bind its command property, if you aren't binding it to a viewmodel, how are you supposed to do it? – J. Doe Feb 02 '20 at 19:59
  • If the UserControl had a Button, its Command property would either bind to an ICommand property of an externally provided (i.e. inherited) view model instance, or the control would itself expose an appropriate ICommand property. It is a big misconceptions of MVVM with WPF that controls have private view models. You'll never find a control, neither in the framework itself, nor in a third part library, that has a private view model. – Clemens Feb 02 '20 at 20:03
  • @Clemens, huh, OK. So if the control doesn't have a viewmodel, how do I go about binding said button's ICommand to (I guess the viewmodel of the parent container?) in such a way that the ICommand would be able to get data from the object the control is displaying information for? – J. Doe Feb 02 '20 at 20:19
  • I think I already mentioned twice that the associated item object from the ItemsSource is *automatically* passed to the DataContext of your control. So if you write `Content="{Binding Name}"` in your control's XAML, it automatically binds to the Name property of the item object. The same of course also works for a command property in the item class. If you want to bind to a command of the parent view model, your control should (as said) expose its own command property, which you would bind explicitly with a RelativeSource binding. But that is another story. – Clemens Feb 02 '20 at 20:29

0 Answers0