Megosztás a következőn keresztül:


Adatmintázás áttekintése

A WPF adatmegjelenítési modell nagy rugalmasságot biztosít az adatok megjelenítésének meghatározásához. A WPF-vezérlők beépített funkciókkal rendelkeznek az adatbemutató testreszabásának támogatásához. Ez a témakör először bemutatja, hogyan definiálhat, DataTemplate majd bevezethet más adatátrendezési funkciókat, például az egyéni logikán alapuló sablonok kiválasztását és a hierarchikus adatok megjelenítésének támogatását.

Előfeltételek

Ez a témakör az adatsablonozási funkciókra összpontosít, és nem az adatkötési koncepciók bevezetője. Az alapvető adatkötési fogalmakkal kapcsolatos információkért tekintse meg az Adatkötés áttekintése című témakört.

DataTemplate az adatok bemutatásáról szól, és egyike a WPF-stílus- és templatingmodell által biztosított számos funkciónak. A WPF-stílus- és templatingmodell bemutatása, például a tulajdonságok vezérlőkre való beállításának módját Style a Stílus és a Templating témakör ismerteti.

Emellett fontos megérteni Resources, amelyek lényegében lehetővé teszik az olyan objektumok, mint például Style és DataTemplate, újrahasználatát. További információ az erőforrásokról: XAML-erőforrások.

A data templating alapjai

Annak bemutatásához, hogy miért DataTemplate fontos, tekintsünk át egy adatkötési példát. Ebben a példában van egy ListBox, amely egy Task objektumlistához van kötve. Minden Task objektumhoz tartozik egy TaskName (sztring), egy Description (sztring), egy Priority (int), és egy TaskType tulajdonság, amely egy Enum típusú, Home és Work értékekkel.

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

DataTemplate nélkül

Nélkül a DataTemplate, a ListBox jelenlegi állapotunk így néz ki:

Képernyőkép az Adatvezetési minta bevezetése ablakról, amelyen a Feladatlistám listamező jelenik meg, megjelenítve az SDKSample.Task sztringábrázolását az egyes forrásobjektumokhoz.

Az történik, hogy konkrét utasítások nélkül a ListBox alapértelmezés szerint meghívja a ToString függvényt, amikor megjeleníti az objektumokat a gyűjteményben. Ezért ha az Task objektum felülbírálja a ToString metódust, akkor a ListBox mögöttes gyűjteményben az egyes forrásobjektumok sztringképe jelenik meg.

Ha például az Task osztály felülbírálja a ToString metódust így, ahol a name mező a TaskName tulajdonsághoz tartozik:

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

Ezután a ListBox következőképpen néz ki:

Képernyőkép a Bevezetés az adattemplatizálási mintához ablakról, amelyen a Saját feladatlista nevű listamező látható, amely a tevékenységek listáját mutatja.

Azonban korlátozó és rugalmatlan. Továbbá, ha XML-adatokhoz kötődne, nem tudná felülbírálni ToString.

Egyszerű DataTemplate definiálása

A megoldás az, hogy meghatározzunk egy DataTemplate. Ennek egyik módja, ha a ItemTemplate tulajdonságot a ListBox egy DataTemplate-ra állítjuk. A megadott DataTemplate adatok az adatobjektum vizuális struktúrájává válnak. Az alábbiak DataTemplate meglehetősen egyszerűek. Útmutatást adunk, hogy minden elem három TextBlock elemként jelenik meg egy adott elemen StackPanelbelül. Minden TextBlock elem az osztály egy tulajdonságához Task van kötve.

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

A jelen témakör példáinak alapjául szolgáló adatok CLR-objektumok gyűjteményei. Ha XML-adatokhoz köti, az alapvető fogalmak megegyeznek, de van némi szintaktikai különbség. Például, ha az XML-csomópont egy attribútuma Path=TaskName, akkor ahelyett, hogy XPath lenne, beállítaná @TaskName értékre TaskName.

ListBox Most a következőhöz hasonlóan néz ki:

Képernyőkép a Bevezetés az adatátvezetési mintába ablakról, amelyen a Saját feladatlista listamező látható, amely a tevékenységeket TextBlock-elemként jeleníti meg.

A DataTemplate létrehozása erőforrásként

A fenti példában soron belül definiáltuk a DataTemplate. Gyakoribb, hogy az erőforrások szakaszban definiáljuk, hogy újrahasználható objektum lehessen, ahogy az alábbi példában is látható:

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

Most már használhatja myTaskTemplate erőforrásként, ahogy az alábbi példában is látható:

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

Mivel myTaskTemplate egy erőforrás, most már más vezérlőkön is használhatja, amelyek DataTemplate típusú értéket vesznek fel. Ahogy fentebb látható, az olyan objektumok esetében, mint például a ItemsControl, a ListBox objektumnál ez a ItemTemplate tulajdonság érvényes. ContentControl objektumok esetében a ContentTemplate tulajdonság.

A DataType tulajdonság

Az DataTemplate osztálynak DataType olyan tulajdonsága van, amely nagyon hasonlít az TargetTypeStyle osztály tulajdonságához. Ezért a fenti példában a x:Key megadásának helyett megteheti a következőket:

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

Ezt DataTemplate a rendszer automatikusan alkalmazza az összes Task objektumra. Vegye figyelembe, hogy ebben az esetben a x:Key beállítás implicit módon történik. Ezért ha ezt DataTemplate az x:Key értéket rendeli hozzá, felülírja az implicit x:Key értéket, és az DataTemplate nem lesz automatikusan alkalmazva.

Ha egy ContentControl-t köt egy Task objektumok gyűjteményéhez, a ContentControl a fent DataTemplate-et nem használja automatikusan. Ennek az az oka, hogy a ContentControl kötéshez több információra van szükség, hogy megkülönböztethessük, hogy egy teljes gyűjteményhez vagy egyes objektumokhoz akarunk-e kötni. ContentControl Ha az ItemsControl típus kiválasztását követi nyomon, a Path kötés ContentControl tulajdonságát "/" értékre állíthatja, hogy jelezze, hogy érdekli az aktuális elem. Egy példa: Egy gyűjteményhez való kötés és információ megjelenítése a kijelölés alapján. Ellenkező esetben explicit módon kell megadnia a DataTemplate-t a ContentTemplate tulajdonság beállításával.

A DataType tulajdonság különösen akkor hasznos, ha különböző típusú adatobjektumokkal rendelkezik CompositeCollection . Példa: CompositeCollection implementálása.

Továbbiak hozzáadása a DataTemplate-hoz

Jelenleg az adatok a szükséges információkkal jelennek meg, de határozottan van még hova fejlődni. Javítsunk a bemutatón egy Border, egy Grid és néhány TextBlock elem hozzáadásával, amelyek leírják a megjelenített adatokat.


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

Az alábbi képernyőképen a ListBox látható a módosított DataTemplate-vel.

Képernyőkép az Adatátvezetési minta bevezetésének ablakáról, amelyen a Saját feladatlista listamező látható a módosított DataTemplate-tal.

HorizontalContentAlignment Stretch Beállíthatjuk, ListBox hogy az elemek szélessége a teljes területet elfoglalja:

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

A(z) HorizontalContentAlignment tulajdonság értéke Stretch-re állítva, a ListBox most így néz ki:

Képernyőkép a Bevezetés az adattemplát minta ablakából, amelyen a Saját Feladatlista listamező vízszintesen van kinyújtva, hogy illeszkedjen a képernyőhöz.

Tulajdonságértékek alkalmazása DataTriggers használatával

Az aktuális bemutató nem árulja el, hogy otthoni vagy irodai feladatról van-e Task szó. Ne feledje, hogy az Task objektumnak van egy TaskType típustulajdonsága TaskType, amely egy számbavétel értékekkel Home és Work.

Az alábbi példában a DataTrigger beállítja az BorderBrush elem border értékét, ha a Yellow tulajdonság TaskType.

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

Az alkalmazás most a következőhöz hasonlóan néz ki. Az otthoni feladatok sárga szegélylel jelennek meg, az irodai feladatok pedig egy aqua szegélyrel jelennek meg:

Képernyőkép az Adattemplatizálási Minta bevezető ablakáról, amely a Saját feladatok listaboxot mutatja, a színes kiemeléssel látható otthoni és irodai feladatok határaival.

Ebben a példában a DataTrigger egy Setter-et használ egy tulajdonságérték beállításához. Az eseményindítóosztályok olyan tulajdonságokkal is rendelkeznek EnterActionsExitActions , amelyek lehetővé teszik műveletek, például animációk indítását. Emellett van egy MultiDataTrigger osztály is, amely lehetővé teszi a módosítások alkalmazását több adathoz kötött tulajdonságérték alapján.

Ugyanezt a hatást úgy érheti el, ha a tulajdonságot a BorderBrushTaskType tulajdonsághoz köti, és egy értékkonverter használatával visszaadja a színt az TaskType érték alapján. A fenti effektus konverterrel történő létrehozása teljesítmény szempontjából kissé hatékonyabb. Emellett a saját konverter létrehozása nagyobb rugalmasságot biztosít, mivel saját logikát biztosít. Végső soron a választott technika a forgatókönyvtől és a preferenciától függ. További információt a konverter írásáról a IValueConverter témakörben talál.

Mi tartozik a DataTemplate-hez?

Az előző példában az eseményindítót a DataTemplate tulajdonság segítségével a DataTemplate.Triggers-ban helyeztük el. Az Setter eseményindító beállítja egy elem (az Border elem) tulajdonságának értékét, amely a DataTemplate -en belül található. Ha azonban az Ön Setters-t érintő tulajdonságok nem az aktuális DataTemplate elemeinek tulajdonságai, akkor célszerűbb lehet ezeknek a tulajdonságoknak a beállítása egy, a Style osztályhoz tartozó ListBoxItem segítségével (ha a kötött vezérlőelem egy ListBox). Például, ha azt szeretné Trigger, hogy az Opacity értéke animálódjon, amikor az egér egy elemre mutat, akkor a ListBoxItem stíluson belül definiálja az eseményindítókat. Példa: Bevezetés a stílus- és templatálási mintába.

Általában tartsa észben, hogy az DataTemplate mindegyik előállított ListBoxItem-re alkalmazva van (a tényleges alkalmazási módjáról és helyéről további információt az ItemTemplate oldalon talál). Az Ön DataTemplate csak az adatok megjelenítésével és kinézetével foglalkozik. A legtöbb esetben a bemutató összes egyéb aspektusa, például hogy néz ki egy elem a kijelöléskor, vagy hogyan ListBox rendezi az elemeket, nem tartoznak a DataTemplate definíciójába. Például tekintse meg az ItemsControl stílus- és templatálási szakaszát .

DataTemplate kiválasztása az adatobjektum tulajdonságai alapján

A DataType Tulajdonság szakaszban bemutattuk, hogy különböző adatsablonokat definiálhat különböző adatobjektumokhoz. Ez különösen akkor hasznos, ha különböző típusú vagy elemeket tartalmazó gyűjteményekkel rendelkezik CompositeCollection. A Tulajdonságértékek alkalmazása a DataTriggers használata szakaszban azt mutattuk be, hogy ha azonos típusú adatobjektum-gyűjteménysel rendelkezik, létrehozhat egy DataTemplate eseményindítót, majd triggerekkel alkalmazhatja a módosításokat az egyes adatobjektumok tulajdonságértékei alapján. Az eseményindítók azonban lehetővé teszik a tulajdonságértékek alkalmazását vagy animációk indítását, de nem teszik lehetővé az adatobjektumok szerkezetének rekonstruálását. Egyes forgatókönyvek esetében előfordulhat, hogy más DataTemplate típusú, de eltérő tulajdonságokkal rendelkező adatobjektumokat kell létrehoznia.

Ha például egy Task objektum Priority értéke 1van, érdemes lehet teljesen más megjelenést adni neki, hogy riasztásként szolgáljon saját magának. Ebben az esetben létrehoz egy DataTemplate objektumot a magas prioritású Task objektumok megjelenítéséhez. Vegyük fel a következőket DataTemplate az erőforrások szakaszba:

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

Ez a példa a DataTemplate.Resources tulajdonságot használja. Az ebben a szakaszban definiált erőforrásokat a DataTemplate elemein belüliek osztják meg.

Annak érdekében, hogy logikát biztosítson az adatobjektum értéke alapján választható DataTemplate kiválasztásához, hozzon létre egy Priority alosztályt, és írja felül a DataTemplateSelector metódust. Az alábbi példában a metódus logikát SelectTemplate biztosít a megfelelő sablon visszaadásához a Priority tulajdonság értéke alapján. A visszaadandó sablon a burkolóelem Window erőforrásaiban található.

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

Ezt követően deklarálhatjuk erőforrásként TaskListDataTemplateSelector :

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

A sablonválasztó erőforrás használatához rendelje hozzá a ItemTemplateSelector tulajdonságához a ListBox-t. A ListBox rendszer meghívja az SelectTemplateTaskListDataTemplateSelector alapul szolgáló gyűjtemény egyes elemeinek metódusát. A hívás elemparaméterként továbbítja az adatobjektumot. A DataTemplate metódus által visszaadott érték ezután az adott adatobjektumra lesz alkalmazva.

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

Miután a sablonválasztó be van állítva, a ListBox így jelenik meg:

Képernyőkép az Adatátrendezés mintaablakról, amelyen a Saját feladatlista listamező látható, amelyen az 1. prioritású tevékenységek láthatók piros szegélyrel.

Ezzel lezárul a példa megvitatása. A teljes minta megtekintéséhez lásd: Bevezetés az adatsablonozási mintába.

ItemsControl stílusa és átformázása

Annak ellenére, hogy a ItemsControl nem az egyetlen vezérlőtípus, amellyel a DataTemplate használható, nagyon gyakori, hogy a ItemsControl egy gyűjteményhez van kötve. A What Belongs in a DataTemplate (Mi tartozik a DataTemplate-ban ) szakaszban azt tárgyaltuk, hogy az Ön DataTemplate definíciójának csak az adatok bemutatásával kell foglalkoznia. Annak érdekében, hogy tudjuk, mikor nem megfelelő a DataTemplate használata, fontos megérteni a különböző stílus- és sablontulajdonságokat, amelyeket a ItemsControl. Az alábbi példa ezeknek a tulajdonságoknak a függvényét szemlélteti. Az ItemsControl ebben a példában szereplő gyűjtemény ugyanahhoz Tasks a gyűjteményhez van kötve, mint az előző példában. Bemutató célokra a példában szereplő stílusok és sablonok mindegyike beágyazottként van deklarálva.

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

A következő képernyőkép a példa renderelésekor látható:

ItemsControl példa képernyőkép

Vegye figyelembe, hogy ahelyett, hogy a függvényt ItemTemplatehasználja, használhatja a ItemTemplateSelector. Egy példaért tekintse meg az előző szakaszt. Hasonlóképpen, ahelyett, hogy a ItemContainerStyle-t használja, lehetőséged van arra, hogy a ItemContainerStyleSelector-t használd.

Az itt nem látható ItemsControl két másik stílushoz kapcsolódó tulajdonsága a GroupStyle és a GroupStyleSelector.

Hierarchikus adatok támogatása

Eddig csak azt vizsgáltuk, hogyan kössünk és jelenítsünk meg egyetlen gyűjteményt. Néha van egy gyűjtemény, amely más gyűjteményeket tartalmaz. Az HierarchicalDataTemplate osztály úgy lett kialakítva, hogy az ilyen adatok megjelenítéséhez a HeaderedItemsControl típusokkal használható legyen. Az alábbi példában ListLeagueList egy League objektumokból álló lista. Minden League objektum rendelkezik egy Name és egy objektumgyűjteménysel Division . Mindegyik Division rendelkezik egy Name és egy objektumgyűjteménysel Team , és mindegyik Team objektumhoz tartozik egy 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>

A példa azt mutatja, hogy a használatával HierarchicalDataTemplateegyszerűen megjelenítheti az egyéb listákat tartalmazó listaadatokat. Az alábbiakban egy képernyőkép látható a példáról.

HierarchicalDataTemplate minta képernyőkép DataBinding_HierarchicalDataTemplate

Lásd még