我试图了解如何最好地扩展ListBox
控件。作为一种学习体验,我想构建一个ListBox
,ListBoxItem
显示CheckBox
而不仅仅是文字。我使用ListBox.ItemTemplate
以基本方式工作,明确设置我想要数据绑定到的属性的名称。一个例子值得千言万语,所以......
我有一个用于数据绑定的自定义对象:
public class MyDataItem {
public bool Checked { get; set; }
public string DisplayName { get; set; }
public MyDataItem(bool isChecked, string displayName) {
Checked = isChecked;
DisplayName = displayName;
}
}
(我构建了一个列表,并将ListBox.ItemsSource
设置为该列表。)我的XAML看起来像这样:
<ListBox Name="listBox1">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=Checked}" Content="{Binding Path=DisplayName}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
这很有效。但我想让这个模板可重用,即我想要绑定到具有除“Checked”和“DisplayName”之外的属性的其他对象。如何修改我的模板,以便我可以将其作为资源,在多个ListBox
实例上重复使用,对于每个实例,将IsChecked
和Content
绑定到任意属性名称?
答案 0 :(得分:17)
将DataTemplate创建为资源,然后使用ListBox的ItemTemplate属性引用它。 MSDN has a good example
<Windows.Resources>
<DataTemplate x:Key="yourTemplate">
<CheckBox IsChecked="{Binding Path=Checked}" Content="{Binding Path=DisplayName}" />
</DataTemplate>
...
</Windows.Resources>
...
<ListBox Name="listBox1"
ItemTemplate="{StaticResource yourTemplate}"/>
答案 1 :(得分:16)
最简单的方法可能是将DataTemplate
作为资源放在应用程序的某处,TargetType
MyDataItem
就像这样
<DataTemplate DataType="{x:Type MyDataItem}">
<CheckBox IsChecked="{Binding Path=Checked}" Content="{Binding Path=DisplayName}" />
</DataTemplate>
您可能还需要在本地程序集中包含xmlns
并通过它引用它。然后,只要您使用ListBox
(或在MyDataItem
或ContentPresenter
中使用ItemsPresenter
的任何其他内容),就会使用此DataTemplate
来显示它。< / p>
答案 2 :(得分:2)
如果您想要单向显示,那么您可以使用转换器:
class ListConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((IList<MyDataItem>)value).Select(i => new { Checked = i.Checked2, DisplayName = i.DisplayName2 });
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后xaml看起来像这样:
<Window.Resources>
<this:ListConverter x:Key="ListConverter" />
</Window.Resources>
<ListBox ItemsSource="{Binding Path=Items, Converter={StaticResource ListConverter}}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=Checked, Mode=OneWay}" Content="{Binding Path=DisplayName, Mode=OneWay}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
您可以像上面那样制作通用的数据模板。双向绑定会更加困难。
我认为您最好使基类实现ICheckedItem接口,该接口公开您希望datatemplates绑定到的通用属性?