如何在WPF DataTemplate中使用DataType属性?

45
很明显我做错了什么,但是似乎无论如何我都无法在使用DataType属性时让HierarchicalDataTemplate(甚至只是DataTemplate)正常工作。我创建了一份最简WPF应用程序来演示这个问题。
XAML:
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
    <Window.Resources>
        <HierarchicalDataTemplate DataType="x:Type local:Foo">
            <TextBlock Text="I am a Foo" />
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="x:Type System:String">
            <TextBlock Text="I am a String" />
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <TreeView Name="treeView1" ItemsSource="{Binding}" />
    </Grid>
</Window>

代码:

namespace WpfApplication1
{
    public class Foo
    {
        public string Name { get; set; }
    }

    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var list = new List<object> { "a", 1, "b", 2, new Foo() { Name="Brian"}};
            treeView1.DataContext = list;
        }
    }
}
显然,我希望它在树视图中显示以下内容。
I am a string
1
I am a string
2
I am a foo

但是我的应用程序实际上显示的是以下内容。

a
1
b
2
WpfApplication1.Foo

奇怪的是,我在网上看到的几乎每个例子都这样做(稍有不同),但似乎没有其他人遇到过这个问题。尽管如此,我已经尝试了无数种重新排列XAML的方法,但没有任何帮助。我希望另一双眼睛能帮忙。

3个回答

63

你的代码没问题,但是你的 DataType 属性值需要用花括号括起来:

<HierarchicalDataTemplate DataType="{x:Type local:Foo}">
    <TextBlock Text="I am a Foo" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type System:String}">
    <TextBlock Text="I am a String" />
</HierarchicalDataTemplate>

6
哈哈...这太尴尬了。我绝对不会告诉你们我花了多长时间来完成这个 :) - Brian Gideon
我认为你也可以使用 DataType="local:Foo"(不需要 x:Type 或花括号),所以不要感到尴尬。这是一个容易犯的错误! - Matt Hamilton
16
@Brian,欢迎来到WPF学习之旅。你会遇到很多这样的问题,不要让它们打击你的信心。 - user7116
谢谢你们的鼓励。WPF与WinForms有很大的不同...但非常酷。到目前为止,我真的很喜欢它。 - Brian Gideon
1
@MattHamilton:“我认为你也可以使用DataType =“local:Foo”(不需要x:Type或花括号)”--顺便说一下,我尝试过那种方式,但它没有起作用。” - Peter Duniho

3

如果你没有使用HierarchicalDataTemplate的ItemsSource,那么最好使用DataTemplate。


是的,实际上我在我的真实应用程序中使用了ItemsSource,但是无论如何这是个好观点。 - Brian Gideon

2

您还没有指定TreeView的ItemTemplate属性。该属性告诉TreeView要使用哪个DataTemplate,在您的情况下,您需要指定在资源中定义的模板:

<TreeView Name="treeView1"
          ItemsSource="{Binding}"
          ItemTemplate="{StaticResource MyResourceItemTemplate}" />

但在您的情况下,您可能实际上想要使用应用于 TreeView.ItemTemplateSelector 属性的 DataTemplateSelector 实现,以根据要显示的类型选择不同的模板...


我是一个 WPF 新手,但我相信当使用数据类型匹配而不是 x:Key 匹配时,ItemTemplate 是不必要的。实际上,Matt 的解决方案有效,所以这一点应该是正确的。是的,DataTemplateSelector 是我的下一个任务。虽然,我认为这次我会有更好的运气。感谢您的时间。 - Brian Gideon
2
如果正确设置,数据类型的DataTemplate可以自动应用于该数据类型。 - Gqqnbig

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