如何使ListBox.ItemTemplate可重用/通用

时间:2009-03-23 23:55:19

标签: c# wpf data-binding itemtemplate

我试图了解如何最好地扩展ListBox控件。作为一种学习体验,我想构建一个ListBoxListBoxItem显示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实例上重复使用,对于每个实例,将IsCheckedContent绑定到任意属性名称?

3 个答案:

答案 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(或在MyDataItemContentPresenter中使用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绑定到的通用属性?

相关问题