我目前没有任何代码可供分享。只是一个设计问题。
我有一个定义标签的类,以及一个关联的条目类型,我想将它绑定到ListBox。如果类型是例如"邮政编码",我需要ListBox将行创建为TextBlock和TextBox。对于"是/否",我需要知道在它旁边创建一个带有CheckBox的TextBlock。这些不同的行类型可能有7个或8个。
最好的方法是什么?
答案 0 :(得分:2)
查看ItemTemplateSelector
属性。此属性允许您提供自定义逻辑,用于选择要用于集合中每个项目的模板。
首先在资源字典中定义各种模板......
<Application>
<Application.Resources>
<DataTemplate x:Key="TextBoxTemplate">
<!-- template here -->
</DataTemplate>
<DataTemplate x:Key="CheckBoxTemplate">
<!-- template here -->
</DataTemplate>
</Application.Resources>
</Application>
然后,创建一个自定义DataTemplateSelector ...
public class MyTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var myObj= item as MyObject;
if (myObj != null)
{
if (myObj.MyType is PostalCode)
{
return Application.Resources["TextBoxTemplate"] as DataTemplate;
}
if (myObj.MyType is YesNo)
{
return Application.Resources["CheckBoxTemplate"] as DataTemplate;
}
}
return null;
}
}
然后,只需使用ItemTemplateSelector
属性......
<Window>
<Window.Resources>
<local:MyTemplateSelector x:Key="tempSelector" />
</Window.Resources>
<ListBox ItemSource="{Binding items}" ItemTemplateSelector="{StaticResource tempSelector}" />
</Window>
答案 1 :(得分:1)
您可以使用DataTrigger 类。
DataTrigger允许您在数据对象的属性值与指定值匹配时设置属性值。
或者,您可以使用DataTemplateSelector 类。
通常,如果对同一类型的对象具有多个DataTemplate,并且希望提供自己的逻辑以根据每个数据对象的属性选择要应用的DataTemplate,则可以创建DataTemplateSelector。
答案 2 :(得分:1)
解决此问题的最佳方法是让一个集合属性包含您希望在ListBox
中看到的所有项目,将该集合绑定到显示项目列表的控件,并使用不同的数据模板,用于更改用于每种类型项目的视觉效果。
例如,您可能有邮政编码类型:
public class PostalCodeEntry
{
public string Value { get; set; } // Implement using standard INotifyPropertyChanged pattern
}
&#34;布尔&#34;类型:
public class BooleanEntry
{
public bool Value { get; set; } // Implement using standard INotifyPropertyChanged pattern
}
你说你想为每个条目类型设置一个标签,所以基类是个好主意:
public abstract class EntryBase
{
public string Label { get; set; } // Implement using standard INotifyPropertyChanged pattern
}
然后BooleanEntry
和PostalCodeEntry
将来自EntryBase
。
Models 已排序。您只需要这些集合,以便可以从UI绑定它们。将适当的集合属性添加到Window
或 ViewModel :
public ObservableCollection<EntryBase> Entries { get; private set; }
在您的UI( View ,在XAML中实现)中,使用一个知道如何绑定到项目列表并将其可视化的控件实例。在WPF中,这将是ItemsControl
或从ListBox
或ListView
获取的控件:
<ItemsControl ItemsSource="{Binding Entries}" />
您可以看到我们如何将ItemsSource
属性绑定到名为Entries
的代码隐藏属性。 ItemsControl
(及其后代)知道如何将这些项转换为可视化表示。默认情况下,您的自定义对象(在我们的示例中为EntryBase
)将转换为字符串并显示为文本块。但是,通过使用data templates,您可以控制从对象到视觉的转换。
如果您将一些数据模板添加到资源部分,如下所示:
<Window ... xmlns:my="clr-namespace:---your namespace here---">
<Window.Resources>
<DataTemplate DataType="{x:Type my:PostalCodeEntry}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Label}" />
<TextBox Text="{Binding Value}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type my:BooleanEntry}">
<CheckBox Content="{Binding Label}" IsChecked="{Binding Value}" />
</DataTemplate>
</Window.Resources>
然后添加<ItemsControl ...
元素,然后您应该会看到TextBlock
类型的TextBox
/ PostalCodeEntry
组合和CheckBox
的{{1}}组合类型。
希望如果能够实现这一目标,它会让您了解如何扩展它以应对其他模型类型及其匹配的数据模板。