Click here to Skip to main content
15,559,455 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm making a WPF Custom Control that consists of a ListBox. The CustomControl has a DependencyProperty that is bound to ItemsSource of the ListBox. For sample's sake, let's assume the ListBox is a collection of Persons with a property called Name, however, it can also be used for other classes as well when required.

What I have tried:

the ListBox looks like this:
XML
<ListBox ItemsSource="{Binding Items, RelativeSource={RelativeSource TemplatedParent}">
     <ListBox.ItemTemplate>
         <DataTemplate>
             <TextBlock Text=""/>
         </DataTemplate>
     </ListBox.ItemTemplate>
</ListBox>


Items is supposed to bind to a class and text in the TextBlock binds to a certain property of that class.

The Properties looks like this:
C#
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(IEnumerable), typeof(SearchListBox), new FrameworkPropertyMetadata(null) { BindsTwoWayByDefault = true });
public static readonly DependencyProperty ClassPropertyProperty = DependencyProperty.Register("ClassProperty", typeof(string), typeof(SearchListBox), new FrameworkPropertyMetadata(null));

public IEnumerable SearchResults
{
   get { return (IEnumerable)GetValue(SearchResultsProperty); }
   set {SetValue(SearchResultsProperty, value); }
}


How can I bind to the property of Person?
Posted
Updated 26-Aug-16 4:04am

I think you can use DisplayMemberPath to be able to dynamically select a named property through ClassProperty to display:
XML
<ListBox ItemsSource="{Binding Items, RelativeSource={RelativeSource TemplatedParent}}"  DisplayMemberPath="{Binding ClassProperty, RelativeSource={RelativeSource TemplatedParent}}">
     </ListBox>

Please note that ItemTemplate cannot be used when DisplayMemberPath is used.

Good luck.
 
Share this answer
 
Comments
Lyandor 25-Aug-16 21:39pm    
Hi Henrik, thank you for your time. I have a few questions regarding your answer:

What if I plan to bind to more than 1 ClassProperties? Let's say the Person class has surname and lastname? As far as I know (which I don't think is a lot) only 1 property can be bound. By Using ItemTemplate, I can make as many TextBlocks as I need to display the properties I want.

Since Items is of type IEnumerable, how do I manage the code behind? Because I have tried this and while I have not tried running it, it doesn't make sense to me:

public string ClassProperty
{
get {return (string)GetValue(Items.GetType().GetProperty(propName));}
}
If you're going to have different data templates in the list box based on type you should do something like this:

<listbox itemssource="{Binding Items, RelativeSource={RelativeSource TemplatedParent}}">
    <listbox.resources>
        <datatemplate datatype="{x:Type viewModels:Person}">
            ...
        </datatemplate>
        <datatemplate datatype="{x:Type viewModels:OtherPossibleItemType}">
            ...
        </datatemplate>
    </listbox.resources>
</listbox>


That way whatever you're displaying will have it's appropriate display based on type and you don't have to add unnecessary metadata. This is also the way WPF is intended to be used.

Of course if your objects are coming from higher level assemblies where it's not appropriate for this scoped ListBox to determine the template, they can be defined in any resource dictionary higher in the visual tree. And even more importantly, if the same template is used in other controls it should be available at the module or application level to avoid redundancy.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900