Brian Gideon
Brian Gideon

Reputation: 48949

How do I use the DataType property on a WPF DataTemplate?

So obviously I am doing something wrong, but I just cannot seem to get the HierarchicalDataTemplate (or even just DataTemplate) to work when using the DataType property. I have created the shortest possible WPF application to demonstrate the problem.

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>

CODE:

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;
        }
    }
}

Obviously I am expecting it display the following in the treeview.

I am a string
1
I am a string
2
I am a foo

But my application actually displays the following.

a
1
b
2
WpfApplication1.Foo

The strange thing is that almost every example I see on the web does this very thing (with slight variations) and no one else seems to be having a problem with it. Yet I have tried countless different ways of rearranging the XAML and nothing seems to help. I am hoping another pair eyes can help.

Upvotes: 47

Views: 75013

Answers (3)

Matt Hamilton
Matt Hamilton

Reputation: 204129

Your code is fine, but your DataType attribute values need to be wrapped in curly braces:

<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>

Upvotes: 66

Josh
Josh

Reputation: 69242

Also if you aren't using the ItemsSource of the HierarchicalDataTemplate you may as well use a DataTemplate instead.

Upvotes: 3

Simon Fox
Simon Fox

Reputation: 10561

You haven't specified the ItemTemplate property of the TreeView. This property tells the TreeView which DataTemplate to use, in your case you want to specify the one defined in your resources:

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

But in your case you may actually want to use a DataTemplateSelector implementation applied to the TreeView.ItemTemplateSelector property for choosing a different template based on the type to be displayed...

Upvotes: 3

Related Questions