Delen via


Overzicht van gegevenssjablonering

Het WPF-datatemplatemodel biedt u grote flexibiliteit bij het definiëren van de presentatie van uw gegevens. WPF-besturingselementen hebben ingebouwde functionaliteit ter ondersteuning van de aanpassing van de gegevenspresentatie. In dit onderwerp wordt eerst gedemonstreert hoe u een DataTemplate definieert en vervolgens andere functies voor gegevensverleiden introduceert, zoals de selectie van sjablonen op basis van aangepaste logica en de ondersteuning voor de weergave van hiërarchische gegevens.

Voorwaarden

Dit onderwerp is gericht op functies voor het templeren van gegevens en is geen introductie van concepten voor gegevensbinding. Zie het Overzicht van gegevensbindingenvoor informatie over basisconcepten voor gegevensbinding.

DataTemplate gaat over de presentatie van gegevens en is een van de vele functies van het WPF-stijl en sjabloonmodel. Zie het onderwerp voor een inleiding over het WPF-styling- en sjabloneringmodel, zoals het gebruik van een Style om eigenschappen van besturingselementen in te stellen.

Daarnaast is het belangrijk om inzicht te krijgen in Resources, die in wezen zijn waarmee objecten zoals Style en DataTemplate herbruikbaar kunnen worden. Zie XAML-resourcesvoor meer informatie over resources.

Basisbeginselen van gegevenssjablonen

Laten we een voorbeeld van een gegevensbinding doorlopen om te laten zien waarom DataTemplate belangrijk is. In dit voorbeeld hebben we een ListBox die is gebonden aan een lijst met Task objecten. Elk Task object heeft een TaskName (tekenreeks), een Description (tekenreeks), een Priority (int) en een eigenschap van het type TaskType, een Enum met waarden Home en Work.

<Window x:Class="SDKSample.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:SDKSample"
  Title="Introduction to Data Templating Sample">
  <Window.Resources>
    <local:Tasks x:Key="myTodoList"/>

</Window.Resources>
  <StackPanel>
    <TextBlock Name="blah" FontSize="20" Text="My Task List:"/>
    <ListBox Width="400" Margin="10"
             ItemsSource="{Binding Source={StaticResource myTodoList}}"/>
  </StackPanel>
</Window>

Zonder DataTemplate

Zonder een DataTemplateziet onze ListBox er momenteel als volgt uit:

schermopname van het venster Inleiding tot gegevens templating-voorbeeld met het keuzelijstvak Mijn takenlijst met de tekenreeksweergave SDKSample.Task voor elk bronobject.

Zonder specifieke instructies roept de ListBox standaard ToString aan wanneer de objecten in de verzameling worden weergegeven. Als het Task object daarom de methode ToString overschrijft, geeft de ListBox de tekenreeksweergave weer van elk bronobject in de onderliggende verzameling.

Als de Task klasse bijvoorbeeld de ToString methode op deze manier overschrijft, waarbij name het veld is voor de eigenschap TaskName:

public override string ToString()
{
    return name.ToString();
}
Public Overrides Function ToString() As String
    Return _name.ToString()
End Function

Vervolgens ziet de ListBox er als volgt uit:

Schermopname van het venster Inleiding tot gegevenssjabloneringvoorbeeld waarin het lijstvak Mijn takenlijst een lijst met taken wordt weergegeven.

Dat is echter beperkend en inflexibel. Als u binding hebt met XML-gegevens, kunt u ToStringniet overschrijven.

Een Simple DataTemplate definiëren

De oplossing is het definiëren van een DataTemplate. Een manier om dat te doen, is door de eigenschap ItemTemplate van de ListBox in te stellen op een DataTemplate. Wat u opgeeft in uw DataTemplate wordt de visuele structuur van uw gegevensobject. De volgende DataTemplate is redelijk eenvoudig. We geven instructies dat elk item wordt weergegeven als drie TextBlock elementen binnen een StackPanel. Elk TextBlock element is gebonden aan een eigenschap van de Task klasse.

<ListBox Width="400" Margin="10"
         ItemsSource="{Binding Source={StaticResource myTodoList}}">
   <ListBox.ItemTemplate>
     <DataTemplate>
       <StackPanel>
         <TextBlock Text="{Binding Path=TaskName}" />
         <TextBlock Text="{Binding Path=Description}"/>
         <TextBlock Text="{Binding Path=Priority}"/>
       </StackPanel>
     </DataTemplate>
   </ListBox.ItemTemplate>
 </ListBox>

De onderliggende gegevens voor de voorbeelden in dit onderwerp zijn een verzameling CLR-objecten. Als u verbinding maakt met XML-gegevens, zijn de basisconcepten hetzelfde, maar er is een klein syntactisch verschil. In plaats van bijvoorbeeld Path=TaskNamete hebben, stelt u XPath in op @TaskName (als TaskName een kenmerk van uw XML-knooppunt is).

De ListBox ziet er nu als volgt uit:

Schermopname van het venster Inleiding tot datatemplating-voorbeeld waarin het ListBox Mijn takenlijst de taken als TextBlock-elementen weergeeft.

DataTemplate als een resource aanmaken

In het bovenstaande voorbeeld hebben we de DataTemplate inline gedefinieerd. Het is gebruikelijker om deze te definiëren in de sectie Resources, zodat het een herbruikbaar object kan zijn, zoals in het volgende voorbeeld:

<Window.Resources>
<DataTemplate x:Key="myTaskTemplate">
  <StackPanel>
    <TextBlock Text="{Binding Path=TaskName}" />
    <TextBlock Text="{Binding Path=Description}"/>
    <TextBlock Text="{Binding Path=Priority}"/>
  </StackPanel>
</DataTemplate>
</Window.Resources>

U kunt nu myTaskTemplate als resource gebruiken, zoals in het volgende voorbeeld:

<ListBox Width="400" Margin="10"
         ItemsSource="{Binding Source={StaticResource myTodoList}}"
         ItemTemplate="{StaticResource myTaskTemplate}"/>

Omdat myTaskTemplate een resource is, kunt u deze nu gebruiken voor andere besturingselementen die een eigenschap hebben die een DataTemplate type gebruikt. Zoals hierboven wordt weergegeven, is het voor ItemsControl objecten, zoals de ListBox, de eigenschap ItemTemplate. Voor ContentControl objecten is dit de eigenschap ContentTemplate.

De eigenschap DataType

De klasse DataTemplate heeft een DataType eigenschap die vergelijkbaar is met de eigenschap TargetType van de klasse Style. Daarom kunt u het volgende doen in plaats van een x:Key op te geven voor de DataTemplate in het bovenstaande voorbeeld:

<DataTemplate DataType="{x:Type local:Task}">
  <StackPanel>
    <TextBlock Text="{Binding Path=TaskName}" />
    <TextBlock Text="{Binding Path=Description}"/>
    <TextBlock Text="{Binding Path=Priority}"/>
  </StackPanel>
</DataTemplate>

Deze DataTemplate wordt automatisch toegepast op alle Task objecten. Houd er rekening mee dat in dit geval de x:Key impliciet wordt ingesteld. Als u deze DataTemplate een x:Key waarde toewijst, overschrijft u daarom de impliciete x:Key en wordt de DataTemplate niet automatisch toegepast.

Als u een ContentControl aan een verzameling Task objecten bindt, gebruikt de ContentControl de bovenstaande DataTemplate niet automatisch. Dit komt doordat de binding op een ContentControl meer informatie nodig heeft om onderscheid te maken of u verbinding wilt maken met een hele verzameling of de afzonderlijke objecten. Als uw ContentControl de selectie van een ItemsControl type bijhoudt, kunt u de eigenschap Path van de ContentControl binding instellen op '/' om aan te geven dat u geïnteresseerd bent in het huidige item. Zie voor een voorbeeld Binden aan een verzameling en informatie weergeven op basis van selectie. Anders moet u de DataTemplate expliciet opgeven door de eigenschap ContentTemplate in te stellen.

De eigenschap DataType is met name handig wanneer u een CompositeCollection van verschillende typen gegevensobjecten hebt. Zie voor een voorbeeld Een CompositeCollection-implementeren.

Meer toevoegen aan de DataTemplate

Momenteel worden de gegevens weergegeven met de benodigde informatie, maar er is zeker ruimte voor verbetering. Laten we de presentatie verbeteren door een Bordertoe te voegen, een Griden enkele TextBlock elementen die de gegevens beschrijven die worden weergegeven.


<DataTemplate x:Key="myTaskTemplate">
  <Border Name="border" BorderBrush="Aqua" BorderThickness="1"
          Padding="5" Margin="5">
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <TextBlock Grid.Row="0" Grid.Column="0" Text="Task Name:"/>
      <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=TaskName}" />
      <TextBlock Grid.Row="1" Grid.Column="0" Text="Description:"/>
      <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/>
      <TextBlock Grid.Row="2" Grid.Column="0" Text="Priority:"/>
      <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>
    </Grid>
  </Border>
</DataTemplate>

In de volgende schermopname ziet u de ListBox met deze gewijzigde DataTemplate:

Schermafbeelding van het voorbeeldvenster van gegevenssjablonering waarin het lijstvak

We kunnen HorizontalContentAlignment instellen op Stretch op de ListBox om ervoor te zorgen dat de breedte van de items de hele ruimte in beslag neemt:

<ListBox Width="400" Margin="10"
     ItemsSource="{Binding Source={StaticResource myTodoList}}"
     ItemTemplate="{StaticResource myTaskTemplate}" 
     HorizontalContentAlignment="Stretch"/>

Nu de eigenschap HorizontalContentAlignment is ingesteld op Stretch, ziet de ListBox er nu als volgt uit:

Schermopname van het venster Inleiding tot voorbeeld van gegevens templating waarin het keuzelijstvak Mijn takenlijst is uitgerekt om horizontaal op het scherm te passen.

DataTriggers gebruiken om eigenschapswaarden toe te passen

In de huidige presentatie wordt niet aangegeven of een Task een thuistaak of een kantoortaak is. Houd er rekening mee dat het Task-object een eigenschap TaskType van het type TaskTypeheeft. Dit is een opsomming met waarden Home en Work.

In het volgende voorbeeld stelt de DataTrigger het BorderBrush van het element met de naam border in op Yellow als de eigenschap TaskType is TaskType.Home.

<DataTemplate x:Key="myTaskTemplate">
<DataTemplate.Triggers>
  <DataTrigger Binding="{Binding Path=TaskType}">
    <DataTrigger.Value>
      <local:TaskType>Home</local:TaskType>
    </DataTrigger.Value>
    <Setter TargetName="border" Property="BorderBrush" Value="Yellow"/>
  </DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>

Onze toepassing ziet er nu als volgt uit. Thuistaken worden weergegeven met een gele rand en kantoortaken worden weergegeven met een aquarand:

Schermopname van het venster Inleiding tot voorbeeld van gegevens templating met het keuzelijstvak Mijn takenlijst met de randen voor thuis- en kantoortaken gemarkeerd in kleur.

In dit voorbeeld gebruikt de DataTrigger een Setter om een eigenschapswaarde in te stellen. De triggerklassen hebben ook de eigenschappen EnterActions en ExitActions waarmee u een set acties zoals animaties kunt starten. Daarnaast is er ook een MultiDataTrigger klasse waarmee u wijzigingen kunt toepassen op basis van meerdere gegevensgebonden eigenschapswaarden.

Een andere manier om hetzelfde effect te bereiken, is door de eigenschap BorderBrush te binden aan de eigenschap TaskType en een waardeconversieprogramma te gebruiken om de kleur te retourneren op basis van de TaskType waarde. Het maken van het bovenstaande effect met behulp van een conversieprogramma is iets efficiënter in termen van prestaties. Bovendien biedt het maken van uw eigen conversieprogramma u meer flexibiliteit omdat u uw eigen logica levert. Welke techniek u kiest, hangt uiteindelijk af van uw scenario en uw voorkeur. Zie IValueConvertervoor meer informatie over het schrijven van een conversieprogramma.

Wat hoort er in een DataTemplate?

In het vorige voorbeeld hebben we de trigger in de DataTemplate geplaatst met behulp van de eigenschap DataTemplate.Triggers. De Setter van de trigger stelt de waarde in van een eigenschap van een element (het Border-element) die zich in de DataTemplatebevindt. Als de eigenschappen waarmee uw Setters zich bezig houden echter geen eigenschappen zijn van elementen die zich in de huidige DataTemplatebevinden, is het mogelijk beter geschikt om de eigenschappen in te stellen met behulp van een Style die voor de ListBoxItem klasse is (als het besturingselement dat u bindt een ListBoxis). Als u bijvoorbeeld wilt dat Trigger de Opacity-waarde van het item animeert wanneer een muis naar een item wijst, definieert u triggers binnen een ListBoxItem-opmaak. Zie voor een voorbeeld de Inleiding tot stijl- en voorbeeldvoorbeelden.

Houd er in het algemeen rekening mee dat de DataTemplate wordt toegepast op elk van de gegenereerde ListBoxItem (zie de ItemTemplate pagina voor meer informatie over hoe en waar deze daadwerkelijk wordt toegepast.) Uw DataTemplate houdt zich alleen bezig met de presentatie en het uiterlijk van de gegevensobjecten. In de meeste gevallen horen alle andere aspecten van de presentatie, zoals hoe een item eruitziet wanneer het wordt geselecteerd of hoe de ListBox de items opgeeft, niet behoren tot de definitie van een DataTemplate. Zie voor een voorbeeld de sectie Styling en Templating van ItemsControl.

Een DataTemplate kiezen op basis van eigenschappen van het gegevensobject

In sectie DataType Property hebben we besproken dat u verschillende gegevenssjablonen voor verschillende gegevensobjecten kunt definiëren. Dit is vooral handig wanneer u een CompositeCollection hebt van verschillende typen of verzamelingen met items van verschillende typen. In het gedeelte DataTriggers gebruiken om eigenschapswaarden toe te passen, hebben we aangetoond dat als u een verzameling van hetzelfde type gegevensobjecten hebt, een DataTemplate kunt maken en vervolgens triggers kunt gebruiken om wijzigingen toe te passen op basis van de eigenschapswaarden van elk gegevensobject. Met triggers kunt u echter eigenschapswaarden toepassen of animaties starten, maar ze bieden u niet de flexibiliteit om de structuur van uw gegevensobjecten te reconstrueren. Voor sommige scenario's moet u mogelijk een andere DataTemplate maken voor gegevensobjecten die van hetzelfde type zijn, maar verschillende eigenschappen hebben.

Als een Task object bijvoorbeeld een Priority waarde van 1heeft, kunt u het een heel ander uiterlijk geven om als waarschuwing voor uzelf te fungeren. In dat geval maakt u een DataTemplate voor de weergave van de objecten met hoge prioriteit Task. Laten we de volgende DataTemplate toevoegen aan de sectie Resources:

<DataTemplate x:Key="importantTaskTemplate">
  <DataTemplate.Resources>
    <Style TargetType="TextBlock">
      <Setter Property="FontSize" Value="20"/>
    </Style>
  </DataTemplate.Resources>
  <Border Name="border" BorderBrush="Red" BorderThickness="1"
          Padding="5" Margin="5">
    <DockPanel HorizontalAlignment="Center">
      <TextBlock Text="{Binding Path=Description}" />
      <TextBlock>!</TextBlock>
    </DockPanel>
  </Border>
</DataTemplate>

In dit voorbeeld wordt de eigenschap DataTemplate.Resources gebruikt. Resources die in die sectie zijn gedefinieerd, worden gedeeld door de elementen in de DataTemplate.

Als u logica wilt opgeven om te kiezen welke DataTemplate u wilt gebruiken op basis van de Priority waarde van het gegevensobject, maakt u een subklasse van DataTemplateSelector en overschrijft u de methode SelectTemplate. In het volgende voorbeeld biedt de methode SelectTemplate logica om de juiste sjabloon te retourneren op basis van de waarde van de eigenschap Priority. De sjabloon die moet worden geretourneerd, vindt u in de resources van het omhullende Window element.

using System.Windows;
using System.Windows.Controls;

namespace SDKSample
{
    public class TaskListDataTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate
            SelectTemplate(object item, DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;

            if (element != null && item != null && item is Task)
            {
                Task taskitem = item as Task;

                if (taskitem.Priority == 1)
                    return
                        element.FindResource("importantTaskTemplate") as DataTemplate;
                else
                    return
                        element.FindResource("myTaskTemplate") as DataTemplate;
            }

            return null;
        }
    }
}

Namespace SDKSample
    Public Class TaskListDataTemplateSelector
        Inherits DataTemplateSelector
        Public Overrides Function SelectTemplate(ByVal item As Object, ByVal container As DependencyObject) As DataTemplate

            Dim element As FrameworkElement
            element = TryCast(container, FrameworkElement)

            If element IsNot Nothing AndAlso item IsNot Nothing AndAlso TypeOf item Is Task Then

                Dim taskitem As Task = TryCast(item, Task)

                If taskitem.Priority = 1 Then
                    Return TryCast(element.FindResource("importantTaskTemplate"), DataTemplate)
                Else
                    Return TryCast(element.FindResource("myTaskTemplate"), DataTemplate)
                End If
            End If

            Return Nothing
        End Function
    End Class
End Namespace

Vervolgens kunnen we de TaskListDataTemplateSelector declareren als een resource:

<Window.Resources>
<local:TaskListDataTemplateSelector x:Key="myDataTemplateSelector"/>
</Window.Resources>

Als u de sjabloonkiezerresource wilt gebruiken, wijst u deze toe aan de eigenschap ItemTemplateSelector van de ListBox. De ListBox roept de SelectTemplate methode van de TaskListDataTemplateSelector aan voor elk van de items in de onderliggende verzameling. De aanroep geeft het gegevensobject door als de itemparameter. De DataTemplate die door de methode wordt geretourneerd, wordt vervolgens toegepast op dat gegevensobject.

<ListBox Width="400" Margin="10"
         ItemsSource="{Binding Source={StaticResource myTodoList}}"
         ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
         HorizontalContentAlignment="Stretch"/>

Nu de sjabloonkiezer is ingesteld, wordt de ListBox nu als volgt weergegeven:

schermopname van het Inleiding tot het gegevens-templatingvoorbeeldvenster met het lijstvak Mijn Takenlijst waarin de taken met Prioriteit 1 duidelijk te zien zijn met een rode rand.

Dit sluit onze bespreking van dit voorbeeld af. Voor het volledige voorbeeld, zie Inleiding tot data-templatesample.

Stylen en sjabloneren van een ItemsControl

Hoewel de ItemsControl niet het enige besturingselementtype is waarmee u een DataTemplate kunt gebruiken, is het een zeer gebruikelijk scenario om een ItemsControl aan een verzameling te binden. In de Wat hoort bij een DataTemplate- sectie hebben we besproken dat de definitie van uw DataTemplate alleen betrekking mag hebben op de presentatie van gegevens. Om te weten wanneer het niet geschikt is voor het gebruik van een DataTemplate is het belangrijk om de verschillende stijl- en sjablooneigenschappen van de ItemsControlte begrijpen. Het volgende voorbeeld is ontworpen om de functie van elk van deze eigenschappen te illustreren. De ItemsControl in dit voorbeeld is gebonden aan dezelfde Tasks verzameling als in het vorige voorbeeld. Voor demonstratiedoeleinden worden de stijlen en sjablonen in dit voorbeeld allemaal inline gedeclareerd.

<ItemsControl Margin="10"
              ItemsSource="{Binding Source={StaticResource myTodoList}}">
  <!--The ItemsControl has no default visual appearance.
      Use the Template property to specify a ControlTemplate to define
      the appearance of an ItemsControl. The ItemsPresenter uses the specified
      ItemsPanelTemplate (see below) to layout the items. If an
      ItemsPanelTemplate is not specified, the default is used. (For ItemsControl,
      the default is an ItemsPanelTemplate that specifies a StackPanel.-->
  <ItemsControl.Template>
    <ControlTemplate TargetType="ItemsControl">
      <Border BorderBrush="Aqua" BorderThickness="1" CornerRadius="15">
        <ItemsPresenter/>
      </Border>
    </ControlTemplate>
  </ItemsControl.Template>
  <!--Use the ItemsPanel property to specify an ItemsPanelTemplate
      that defines the panel that is used to hold the generated items.
      In other words, use this property if you want to affect
      how the items are laid out.-->
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <WrapPanel />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <!--Use the ItemTemplate to set a DataTemplate to define
      the visualization of the data objects. This DataTemplate
      specifies that each data object appears with the Proriity
      and TaskName on top of a silver ellipse.-->
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <DataTemplate.Resources>
        <Style TargetType="TextBlock">
          <Setter Property="FontSize" Value="18"/>
          <Setter Property="HorizontalAlignment" Value="Center"/>
        </Style>
      </DataTemplate.Resources>
      <Grid>
        <Ellipse Fill="Silver"/>
        <StackPanel>
          <TextBlock Margin="3,3,3,0"
                     Text="{Binding Path=Priority}"/>
          <TextBlock Margin="3,0,3,7"
                     Text="{Binding Path=TaskName}"/>
        </StackPanel>
      </Grid>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
  <!--Use the ItemContainerStyle property to specify the appearance
      of the element that contains the data. This ItemContainerStyle
      gives each item container a margin and a width. There is also
      a trigger that sets a tooltip that shows the description of
      the data object when the mouse hovers over the item container.-->
  <ItemsControl.ItemContainerStyle>
    <Style>
      <Setter Property="Control.Width" Value="100"/>
      <Setter Property="Control.Margin" Value="5"/>
      <Style.Triggers>
        <Trigger Property="Control.IsMouseOver" Value="True">
          <Setter Property="Control.ToolTip"
                  Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                          Path=Content.Description}"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </ItemsControl.ItemContainerStyle>
</ItemsControl>

Hier volgt een schermopname van het voorbeeld wanneer het wordt weergegeven:

Voorbeeldschermopname van ItemsControl

In plaats van de ItemTemplatete gebruiken, kunt u de ItemTemplateSelectorgebruiken. Raadpleeg de vorige sectie voor een voorbeeld. In plaats van de ItemContainerStylete gebruiken, hebt u ook de mogelijkheid om de ItemContainerStyleSelectorte gebruiken.

Twee andere stijlgerelateerde eigenschappen van de ItemsControl die hier niet worden weergegeven, zijn GroupStyle en GroupStyleSelector.

Ondersteuning voor hiërarchische gegevens

Tot nu toe hebben we alleen gekeken naar hoe we één verzameling kunnen binden en weergeven. Soms hebt u een verzameling die andere verzamelingen bevat. De HierarchicalDataTemplate klasse is ontworpen voor gebruik met HeaderedItemsControl typen om dergelijke gegevens weer te geven. In het volgende voorbeeld is ListLeagueList een lijst met League objecten. Elk League-object heeft een Name en een verzameling Division objecten. Elke Division heeft een Name en een verzameling Team objecten en elk Team-object heeft een Name.

<Window x:Class="SDKSample.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="HierarchicalDataTemplate Sample"
  xmlns:src="clr-namespace:SDKSample">
  <DockPanel>
    <DockPanel.Resources>
      <src:ListLeagueList x:Key="MyList"/>

      <HierarchicalDataTemplate DataType    = "{x:Type src:League}"
                                ItemsSource = "{Binding Path=Divisions}">
        <TextBlock Text="{Binding Path=Name}"/>
      </HierarchicalDataTemplate>

      <HierarchicalDataTemplate DataType    = "{x:Type src:Division}"
                                ItemsSource = "{Binding Path=Teams}">
        <TextBlock Text="{Binding Path=Name}"/>
      </HierarchicalDataTemplate>

      <DataTemplate DataType="{x:Type src:Team}">
        <TextBlock Text="{Binding Path=Name}"/>
      </DataTemplate>
    </DockPanel.Resources>

    <Menu Name="menu1" DockPanel.Dock="Top" Margin="10,10,10,10">
        <MenuItem Header="My Soccer Leagues"
                  ItemsSource="{Binding Source={StaticResource MyList}}" />
    </Menu>

    <TreeView>
      <TreeViewItem ItemsSource="{Binding Source={StaticResource MyList}}" Header="My Soccer Leagues" />
    </TreeView>

  </DockPanel>
</Window>

In het voorbeeld ziet u dat u met het gebruik van HierarchicalDataTemplateeenvoudig lijstgegevens kunt weergeven die andere lijsten bevatten. Hier volgt een schermopname van het voorbeeld.

schermopname van HierarchicalDataTemplate-voorbeeldschermopname

Zie ook