I'm trying to list some strings in a Silverlight ListBox. I'm binding a vanilla List
to the ItemsSource
and then specifying the property of the List item to display in DisplayMemberPath
. There is something specific to my implementation that causes the ListBox to display the templated items instead of the property specified inside those items.
Here's the scenario. I have a Parent class that derives from UserControl
that adds a "Title" Dependency Property. I create a few Child controls that derive from Parent and specify that inherited Title property. For some reason, binding to that Title property in the ListBox causes the unexpected behavior. Here's the code:
public class Parent : UserControl
{
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
// Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(Parent), new PropertyMetadata(String.Empty));
}
The Child XAML code (Child1 and Child2 are basically the same XAML with trivial codebehinds)
<v:Parent x:Class="TemplateBindingTest.Child1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:v="clr-namespace:TemplateBindingTest"
mc:Ignorable="d" Title="Baby 1" Height="41" Width="94">
<Grid x:Name="LayoutRoot" Background="#FFFFBBBB">
<TextBlock HorizontalAlignment="Center" Text="I da baby" VerticalAlignment="Center" FontSize="14" />
</Grid>
The "ViewModel"
public class TheViewModel : INotifyPropertyChanged
{
public List<Parent> Babies { get; set; }
public TheViewModel()
{
Babies = new List<Parent>();
Child1 baby1 = new Child1();
Child2 baby2 = new Child2();
Babies.Add(baby1);
Babies.Add(baby2);
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainPage.xaml
<UserControl x:Class="TemplateBindingTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" xmlns:my="clr-namespace:TemplateBindingTest" Height="268" Width="355">
<Grid x:Name="LayoutRoot" Background="White">
<ListBox ItemsSource="{Binding Path=Babies}" DisplayMemberPath="Title" Height="219" HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="180" />
<my:Child1 HorizontalAlignment="Left" Margin="203,26,0,0" x:Name="child1" VerticalAlignment="Top" />
<my:Child2 HorizontalAlignment="Left" Margin="203,92,0,0" x:Name="child2" VerticalAlignment="Top" />
</Grid>
So ignoring the fact that it's a bit weird to maintain a list of UI controls in a "viewmodel" class, this is all fairly simple Silverlight. In the ListBox control on MainPage I would expect to see the title for each Child control. Instead, the Child controls themselves show up in the ListBox. What am I missing here? I find it very odd that Silverlight just decides to render the Children controls with no complaints in the Debug Output or other error messages. It's like the DisplayMemberPath
attribute gets completely ignored. Could this be a bug in Silverlight?
For ease of testing, here's a link to the full Visual Studio project containing the code above.