简体   繁体   English

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

[英]How to make a ListBox.ItemTemplate reusable/generic

I am trying to understand how best to extend the ListBox control.我试图了解如何最好地扩展ListBox控件。 As a learning experience, I wanted to build a ListBox whose ListBoxItem s display a CheckBox instead of just text.作为学习经验,我想构建一个ListBox ,其ListBoxItem s 显示CheckBox而不仅仅是文本。 I got that working in a basic fashion using the ListBox.ItemTemplate , explicitly setting the names of the properties I wanted to databind to.我使用ListBox.ItemTemplate以基本方式工作,明确设置我想要数据绑定到的属性的名称。 An example is worth a thousand words, so...一个例子值一千字,所以...

I've got a custom object for databinding:我有一个自定义 object 用于数据绑定:

public class MyDataItem {
    public bool Checked { get; set; }
    public string DisplayName { get; set; }

    public MyDataItem(bool isChecked, string displayName) {
        Checked = isChecked;
        DisplayName = displayName;
    }
}

(I build a list of those and set ListBox.ItemsSource to that list.) And my XAML looks like this: (我建立了一个列表并将ListBox.ItemsSource设置为该列表。)我的 XAML 看起来像这样:

<ListBox Name="listBox1">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Path=Checked}" Content="{Binding Path=DisplayName}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

This works.这行得通。 But I want to make this template reusable, ie I'll want to bind to other objects with properties other than "Checked" and "DisplayName".但我想让这个模板可重用,即我想绑定到具有除“Checked”和“DisplayName”之外的属性的其他对象。 How can I modify my template such that I could make it a resource, reuse it on multiple ListBox instances, and for each instance, bind IsChecked and Content to arbitrary property names?如何修改我的模板,使其成为资源,在多个ListBox实例上重用它,并为每个实例将IsCheckedContent绑定到任意属性名称?

Create your DataTemplate as a resource and then reference it using the ItemTemplate property of the ListBox.将 DataTemplate 创建为资源,然后使用 ListBox 的 ItemTemplate 属性引用它。 MSDN has a good example MSDN 有一个很好的例子

<Windows.Resources>
  <DataTemplate x:Key="yourTemplate">
    <CheckBox IsChecked="{Binding Path=Checked}" Content="{Binding Path=DisplayName}" />
  </DataTemplate>
...
</Windows.Resources>

...
<ListBox Name="listBox1"
         ItemTemplate="{StaticResource yourTemplate}"/>

The easiest way is probably to put the DataTemplate as a resource somewhere in your application with a TargetType of MyDataItem like this最简单的方法可能是将DataTemplate作为资源放在应用程序中的某个位置, MyDataItem TargetType如下所示

<DataTemplate DataType="{x:Type MyDataItem}">
    <CheckBox IsChecked="{Binding Path=Checked}" Content="{Binding Path=DisplayName}" />
</DataTemplate>

You'll probably also have to include an xmlns to your local assembly and reference it through that.您可能还必须在本地程序集中包含一个xmlns并通过它引用它。 Then whenever you use a ListBox (or anything else that uses a MyDataItem in a ContentPresenter or ItemsPresenter ) it will use this DataTemplate to display it.然后,每当您使用ListBox (或在ContentPresenterItemsPresenter中使用MyDataItem的任何其他东西)时,它将使用此DataTemplate来显示它。

If you wanted one way display then you could use a converter:如果您想要一种方式显示,那么您可以使用转换器:

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();
    }
}

Then the xaml would look something like this:然后 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>

That data template you could make generic like above.您可以像上面那样通用的那个数据模板。 Two way binding would be a fair bit more difficult.双向绑定会更困难一些。

I think you are better off making your base classes implement a ICheckedItem interface which exposes the generic properties that you want the datatemplates to bind to?我认为您最好让您的基类实现一个 ICheckedItem 接口,该接口公开您希望数据模板绑定到的通用属性?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否有一个RichTextBox等效于ListBox.ItemTemplate? - Is there a RichTextBox equivalent to a ListBox.ItemTemplate? ListBox.ItemTemplate内部的图像如何在点击时更改不透明度 - Image inside ListBox.ItemTemplate how to change opacity on tap 如何在Windows Phone 7中以编程方式创建ListBox.Itemtemplate,datatemplate - How to create ListBox.Itemtemplate,datatemplate programatically in Windows Phone 7 DataTrigger在ListBox.ItemTemplate中不起作用 - DataTrigger not working within a ListBox.ItemTemplate 将属性绑定到创建的每个ListBox.ItemTemplate - Bind property to each ListBox.ItemTemplate created 带有长文本的ListBox.ItemTemplate与ListBox宽度不匹配 - ListBox.ItemTemplate with long text does not match ListBox width 如何从ListBox.ItemTemplate DataTemplate内部调用Button命令以传递参数而不选择ListBox项目? - How do I call Button command from inside of ListBox.ItemTemplate DataTemplate, to pass parameter without selecting ListBox item? WPF MVVM ListBox.ItemTemplate CheckBox IsChecked绑定 - WPF MVVM ListBox.ItemTemplate CheckBox IsChecked binding ListBox.ItemTemplate在DataTemplate内部具有自定义控件模板 - ListBox.ItemTemplate with a custom control template inside DataTemplate 在Listbox.ItemTemplate中找到控件(WPF C#) - Find control inside Listbox.ItemTemplate (WPF C#)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM