如何使用DataTemplates支持ListBox的继承

时间:2015-04-08 12:36:53

标签: c# wpf

我有一个ListBox,它的数据源是一些可观察的一些对象数组。这些对象都是从基类派生的。

我试图给每个数组实例一个特定的数据模板来处理它与其他实例的差异。

abstract class Base
{
    public string a {get; set;};
}
class sub1 : Base
{
    public string prop1 {get; set;};
}
class sub2 : Base
{
    public string prop2 {get; set;};
}

如果数组包含两个实例,一个是sub1,另一个是sub2,列表框应该显示第一个属性a和prop1,第二个实例是a和prop2。

请指教,

2 个答案:

答案 0 :(得分:4)

您可以创建DataTemplateSelector

public class MyTemplateSelector : DataTemplateSelector
{
    public DataTemplate Sub1Template { get; set; }
    public DataTemplate Sub2Template { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is sub1) { return Sub1Template; }
        if (item is sub2) { return Sub2Template; }

        return null;
    }
}

然后按如下方式使用:

<UserControl>
    <UserControl.Resources>
        <DataTemplate x:Key="TemplateForSub1">
            <StackPanel>
                <TextBlock Text="{Binding a}" />
                <TextBlock Text="{Binding prop1}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="TemplateForSub2">
            <StackPanel>
                <TextBlock Text="{Binding a}" />
                <TextBlock Text="{Binding prop2}" />
            </StackPanel>
        </DataTemplate>
        <my:MyTemplateSelector x:Key="MySelector"
                               Sub1Template="{StaticResource TemplateForSub1}"
                               Sub2Template="{StaticResource TemplateForSub2}" />
    </UserControl.Resources>
    <ListBox ItemsSource="{Binding SomeCollectionSomewhere}"
             ItemTemplateSelector="{StaticResource MySelector}" />
</UserControl>

这应该让你开始。

更新:您当然可以使用<DataTemplate DataType="{x:Type ...}" ...>严格根据项目类型选择数据模板。在许多情况下这样做可能更简单。 DataTemplateSelector可以提供DataType=无法提供的一些灵活性,例如根据类中的值更改模板,或方法调用的结果等。选择适合您的任何一种。

答案 1 :(得分:2)

您需要为要显示的每种类型指定模板。尝试这样的事情:

<ListBox ItemsSource="{Binding MyArray}">
  <ListBox.Resources>
    <DataTemplate DataType="{x:Type local:sub1}">
      <StackPanel>
        <TextBlock Text="{Binding a}"/>
        <TextBlock Text="{Binding prop1}"/>
      </StackPanel>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:sub2}">
      <StackPanel>
        <TextBlock Text="{Binding a}"/>
        <TextBlock Text="{Binding prop2}"/>
      </StackPanel>
    </DataTemplate>
  </ListBox.Resources>
</ListBox>

MyArray是包含您的实例的数组。 local是类sub1和sub2

的命名空间