C# 如何使 ListBox.ItemTemplate 可重用/通用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/675671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make a ListBox.ItemTemplate reusable/generic
提问by Matt Winckler
I am trying to understand how best to extend the ListBox
control. As a learning experience, I wanted to build a ListBox
whose ListBoxItem
s display a CheckBox
instead of just text. I got that working in a basic fashion using the ListBox.ItemTemplate
, explicitly setting the names of the properties I wanted to databind to. An example is worth a thousand words, so...
我试图了解如何最好地扩展ListBox
控制。作为学习经验,我想构建一个ListBox
who ListBoxItem
s 显示 aCheckBox
而不仅仅是文本。我使用 以基本方式工作ListBox.ItemTemplate
,显式设置我想要数据绑定到的属性的名称。一个例子胜过一千个字,所以……
I've got a custom object for databinding:
我有一个用于数据绑定的自定义对象:
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, i.e. I'll want to bind to other objects with properties other than "Checked" and "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?
这有效。但我想让这个模板可重用,即我想绑定到具有“Checked”和“DisplayName”以外的属性的其他对象。如何修改我的模板,这样我可以让它变成一个资源,再用它在多个ListBox
实例,每个实例,绑定IsChecked
和Content
任意属性名称?
采纳答案by Bryan Anderson
The easiest way is probably to put the DataTemplate
as a resourcesomewhere in your application with a TargetType
of MyDataItem
like this
最简单的方法可能是将资源DataTemplate
作为资源放在您的应用程序中的某个地方TargetType
,MyDataItem
就像这样
<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. 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.
您可能还必须xmlns
在本地程序集中包含一个并通过它引用它。然后,每当您使用 a ListBox
(或MyDataItem
在 aContentPresenter
或中使用 a 的任何其他内容ItemsPresenter
)时,它将使用它DataTemplate
来显示它。
回答by MrTelly
Create your DataTemplate as a resource and then reference it using the ItemTemplate property of the ListBox. MSDN has a good example
创建您的 DataTemplate 作为资源,然后使用 ListBox 的 ItemTemplate 属性引用它。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}"/>
回答by Jake Ginnivan
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 接口,该接口公开您希望数据模板绑定到的通用属性?