web-dev-qa-db-fra.com

Comment utiliser la propriété DataType sur un DataTemplate WPF?

Donc, évidemment, je fais quelque chose de mal, mais je n'arrive pas à faire fonctionner le HierarchicalDataTemplate (ou même simplement DataTemplate) lors de l'utilisation de la propriété DataType. J'ai créé l'application WPF la plus courte possible pour illustrer le problème.

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

Évidemment, je m'attends à ce qu'il affiche ce qui suit dans l'arborescence.

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

Mais mon application affiche en fait ce qui suit.

a
1
b
2
WpfApplication1.Foo

Ce qui est étrange, c'est que presque tous les exemples que je vois sur le Web le font (avec de légères variations) et personne d'autre ne semble avoir de problème avec cela. Pourtant, j'ai essayé d'innombrables façons différentes de réorganiser le XAML et rien ne semble aider. J'espère qu'une autre paire d'yeux pourra aider.

37
Brian Gideon

Votre code est correct, mais vos valeurs d'attribut DataType doivent être placées entre accolades:

<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>
51
Matt Hamilton

De plus, si vous n'utilisez pas le ItemsSource du HierarchicalDataTemplate, vous pouvez également utiliser un DataTemplate à la place.

3
Josh

Vous n'avez pas spécifié la propriété ItemTemplate de TreeView. Cette propriété indique à TreeView quel DataTemplate utiliser, dans votre cas, vous souhaitez spécifier celui défini dans vos ressources:

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

Mais dans votre cas, vous souhaiterez peut-être utiliser une implémentation DataTemplateSelector appliquée à TreeView.ItemTemplateSelector propriété pour choisir un modèle différent en fonction du type à afficher ...

2
Simon Fox