在WPF ListBox中如何从单个列表中显示多种类型?

10

我有一个包含两种不同类型的ObservableCollection<Object>

我想将此列表绑定到一个ListBox,并为遇到的每种类型显示不同的DataTemplates。 我无法弄清楚如何根据类型自动切换数据模板。

我尝试使用DataTemplate的DataType属性,尝试使用ControlTemplates和DataTrigger,但都没有成功,要么什么也不显示,要么它声称找不到我的类型...

以下是尝试示例:

现在我只连接了一个数据模板到ListBox,但即使如此也不起作用。

XAML:

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
    <DataTemplate x:Key="PersonTemplate">
        <TextBlock Text="{Binding Path=Name}"></TextBlock>
    </DataTemplate>

    <DataTemplate x:Key="QuantityTemplate">
        <TextBlock Text="{Binding Path=Amount}"></TextBlock>
    </DataTemplate>

</Window.Resources>
<Grid>
    <DockPanel>
        <ListBox x:Name="MyListBox" Width="250" Height="250" 
ItemsSource="{Binding Path=ListToBind}"
ItemTemplate="{StaticResource PersonTemplate}"></ListBox>
    </DockPanel>
</Grid>
</Window>

后台代码:

public class Person
{
    public string Name { get; set; }

    public Person(string name)
    {
        Name = name;
    }
}

public class Quantity
{
    public int Amount { get; set; }

    public Quantity(int amount)
    {
        Amount = amount;
    }
}

public partial class Window1 : Window
{
    ObservableCollection<object> ListToBind = new ObservableCollection<object>();

    public Window1()
    {
        InitializeComponent();

        ListToBind.Add(new Person("Name1"));
        ListToBind.Add(new Person("Name2"));
        ListToBind.Add(new Quantity(123));
        ListToBind.Add(new Person("Name3"));
        ListToBind.Add(new Person("Name4"));
        ListToBind.Add(new Quantity(456));
        ListToBind.Add(new Person("Name5"));
        ListToBind.Add(new Quantity(789));
    }
}
2个回答

7
你说“它声称找不到我的类型”,这是一个需要解决的问题。
最有可能的问题是你没有在XAML中创建一个命名空间声明,来引用你的CLR命名空间和程序集。你需要在XAML的顶层元素中放置类似于以下内容的声明:
xmlns:foo="clr-namespace:MyNamespaceName;assembly=MyAssemblyName"

一旦你这样做了,XAML就会知道任何带有XML命名空间前缀foo的东西实际上是MyNamespaceName命名空间中MyAssemblyName类。然后,在创建DataTemplate的标记中,您可以引用该XML命名空间:
<DataTemplate DataType="{foo:Person}">

您当然可以建立一个模板选择器,但这会给您的软件添加不必要的负担。在 WPF 应用程序中有适合模板选择器的位置,但这不是它的位置。


2
+1 你说得对。我想知道为什么我从来没有看到这个非常酷的选项。这里是 MSDN 链接:http://msdn.microsoft.com/zh-cn/library/system.windows.datatemplate.datatype.aspx - HCL
数据模板选择器一旦我放进去,似乎就变得多余了。感谢您的建议。我想肯定有一种简单的方法来解决这个问题,而您已经提供了它! - davisoa
1
<DataTemplate DataType="{foo:Person}"> 对我不起作用,但是 <DataTemplate DataType="{x:Type foo:Person}"> 起作用了。打错了吗? - Anton

6

1
你不必使用模板选择器;WPF的默认模板选择方法在此处完全符合要求。 - Robert Rossney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接