tags:

views:

329

answers:

3

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.

A: 

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

Simon Fox
I am a WPF newbie, but I believe ItemTemplate is not required when using data type matches as opposed x:Key matches. Actually, Matt's solution works so that must be the case. And yes, DataTemplateSelector is my next task. Though, I think I will have better luck this time. Thanks for your time.
Brian Gideon
+5  A: 

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
Matt Hamilton
Haha...that is so embarrassing. There is 100% no way I am telling any of you how long I spent working on this :)
Brian Gideon
I *think* you can also get away with DataType="local:Foo" (without the x:Type or the curly braces), so don't be embarrassed. It's an easy mistake to make!
Matt Hamilton
@Brian, welcome to the WPF learning curve. You will come across MANY of these, don't let them get you down.
sixlettervariables
Thanks for the encouragement both of you. WPF is so much different than WinForms...but very cool. I really like what I have seen so far.
Brian Gideon
+1  A: 

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

Josh Einstein
Yeah, actually I am using ItemsSource in my real application, but good point nevertheless.
Brian Gideon