2010-08-03 54 views
10

我对WPF比较陌生,它看起来像可能有一堆方法来做到这一点,但我不能得到任何我尝试过的工作。从WPF列表框的单个列表中显示多种类型?

我有一个ObservableCollection包含两种不同的类型。

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

我已经尝试使用DataTemplate中的数据类型属性和使用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)); 
    } 
} 

回答

6

你说

Addiontal信息,“它声称它无法找到我的类型。”这是你应该修复的问题。

问题很可能是您没有在引用您的CLR命名空间和程序集的XAML中创建名称空间声明。你需要把这样的事情在XAML的顶级元素:

xmlns:foo="clr-namespace:MyNamespaceName;assembly=MyAssemblyName" 

一旦你这样做,XAML就知道与XML命名空间前缀foo东西实际上是MyAssemblyNameMyNamespaceName命名空间中的类。

然后可以引用XML命名空间中创建该DataTemplate的标记:

<DataTemplate DataType="{foo:Person}"> 

你当然可以建立一个模板选择,但是这增加了一块克鲁夫特到您的软件,不需要在那里。在WPF应用程序中有一个模板选择器的地方,但事实并非如此。

+2

+1你说得对。我想知道为什么我从来没有见过这个非常酷的选择。在这里,MSDN链接:http://msdn.microsoft.com/en-us/library/system.windows.datatemplate.datatype.aspx – HCL 2010-08-04 07:10:09

+0

的DataTemplateSelector似乎像一次克鲁夫特我把这个感谢您的建议。我觉得必须有一个简单的方法来解决这个问题,而且你已经提供了它! – davisoa 2010-08-04 14:47:36

+1

不为我工作,但一样。错字? – 2014-03-06 11:21:30

6

你必须使用一个DataTemplateSelector。一个例子见here。在MSDN

+0

这就像一个魅力!谢谢! – davisoa 2010-08-03 21:28:09

+1

您不必使用模板选择器; WPF的默认模板选择方法正是这里所需要的。 – 2010-08-04 00:58:32