Bagikan melalui


Gambaran Umum Templat Data

Model templat data WPF memberi Anda fleksibilitas yang besar untuk menentukan presentasi data Anda. Kontrol WPF memiliki fungsionalitas bawaan untuk mendukung penyesuaian presentasi data. Topik ini pertama-tama menunjukkan cara menentukan DataTemplate dan kemudian memperkenalkan fitur templat data lainnya, seperti pemilihan templat berdasarkan logika kustom dan dukungan untuk tampilan data hierarkis.

Prasyarat

Topik ini berfokus pada fitur templat data dan bukan pengenalan konsep pengikatan data. Untuk informasi tentang konsep pengikatan data dasar, lihat Gambaran Umum Pengikatan Data.

DataTemplate adalah tentang presentasi data dan merupakan salah satu dari banyak fitur yang disediakan oleh model gaya dan templat WPF. Untuk pengenalan model gaya dan templat WPF, seperti cara menggunakan Style untuk mengatur properti pada kontrol, lihat topik Gaya dan Templat .

Selain itu, penting untuk memahami Resources, yang pada dasarnya apa yang memungkinkan objek seperti Style dan DataTemplate dapat digunakan kembali. Untuk informasi selengkapnya tentang sumber daya, lihat Sumber Daya XAML.

Dasar-Dasar Templat Data

Untuk menunjukkan mengapa DataTemplate penting, mari kita telusuri contoh pengikatan data. Dalam contoh ini, kita memiliki ListBox yang terikat ke daftar Task objek. Setiap Task objek memiliki TaskName (string), Description (string), Priority (int), dan properti jenis TaskType, yang merupakan Enum dengan nilai Home dan 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>

Tanpa DataTemplate

DataTemplateTanpa , saat ini kami ListBox terlihat seperti ini:

Screenshot of the Introduction to Data Templating Sample window showing the My Task List ListBox displaying the string representation SDKSample.Task for each source object.

Apa yang terjadi adalah bahwa tanpa instruksi tertentu, ListBox panggilan ToString secara default saat mencoba menampilkan objek dalam koleksi. Oleh karena itu, jika Task objek mengambil ToString alih metode , maka ListBox menampilkan representasi string dari setiap objek sumber dalam koleksi yang mendasar.

Misalnya, jika Task kelas mengambil alih metode dengan ToString cara ini, di mana name adalah bidang untuk TaskName properti:

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

Kemudian terlihat ListBox seperti berikut ini:

Screenshot of the Introduction to Data Templating Sample window showing the My Task List ListBox displaying a list of tasks.

Namun, itu membatasi dan tidak fleksibel. Selain itu, jika Anda mengikat data XML, Anda tidak akan dapat mengambil alih ToString.

Menentukan DataTemplate Sederhana

Solusinya adalah mendefinisikan DataTemplate. Salah satu cara untuk melakukan itu adalah dengan mengatur ItemTemplate properti ke ListBoxDataTemplate. Apa yang Anda tentukan dalam DataTemplate menjadi struktur visual objek data Anda. Berikut ini DataTemplate cukup sederhana. Kami memberikan instruksi bahwa setiap item muncul sebagai tiga TextBlock elemen dalam .StackPanel Setiap TextBlock elemen terikat ke properti Task kelas.

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

Data yang mendasar untuk contoh dalam topik ini adalah kumpulan objek CLR. Jika Anda mengikat data XML, konsep dasarnya sama, tetapi ada sedikit perbedaan sinaks. Misalnya, alih-alih memiliki Path=TaskName, Anda akan mengatur XPath ke @TaskName (jika TaskName merupakan atribut dari simpul XML Anda).

Sekarang tampilan kita ListBox seperti berikut:

Screenshot of the Introduction to Data Templating Sample window showing the My Task List ListBox displaying the tasks as TextBlock elements.

Membuat DataTemplate sebagai Sumber Daya

Dalam contoh di atas, kami mendefinisikan sebaris DataTemplate . Lebih umum untuk menentukannya di bagian sumber daya sehingga dapat menjadi objek yang dapat digunakan kembali, seperti dalam contoh berikut:

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

Sekarang Anda dapat menggunakan myTaskTemplate sebagai sumber daya, seperti dalam contoh berikut:

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

Karena myTaskTemplate merupakan sumber daya, Anda sekarang dapat menggunakannya pada kontrol lain yang memiliki properti yang mengambil DataTemplate jenis. Seperti yang ditunjukkan di atas, untuk ItemsControl objek, seperti ListBox, itu adalah ItemTemplate properti . Untuk ContentControl objek, ini adalah ContentTemplate properti .

Properti DataType

Kelas DataTemplate ini memiliki DataType properti yang sangat mirip TargetType dengan properti Style kelas. Oleh karena itu, alih-alih menentukan x:Key untuk DataTemplate dalam contoh di atas, Anda dapat melakukan hal berikut:

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

Ini DataTemplate akan diterapkan secara otomatis ke semua Task objek. Perhatikan bahwa dalam hal x:Key ini diatur secara implisit. Oleh karena itu, jika Anda menetapkan nilai ini DataTemplatex:Key , Anda mengesampingkan implisit x:Key dan DataTemplate tidak akan diterapkan secara otomatis.

Jika Anda mengikat ContentControl ke kumpulan Task objek, ContentControl jangan gunakan yang di atas DataTemplate secara otomatis. Ini karena pengikatan pada ContentControl kebutuhan informasi lebih lanjut untuk membedakan apakah Anda ingin mengikat seluruh koleksi atau objek individual. Jika Anda ContentControl melacak pilihan ItemsControl jenis, Anda dapat mengatur Path properti pengikatan ContentControl ke "/" untuk menunjukkan bahwa Anda tertarik dengan item saat ini. Misalnya, lihat Mengikat ke Koleksi dan Menampilkan Informasi Berdasarkan Pilihan. Jika tidak, Anda perlu menentukan DataTemplate secara eksplisit dengan mengatur ContentTemplate properti .

Properti DataType ini sangat berguna ketika Anda memiliki CompositeCollection berbagai jenis objek data. Misalnya, lihat Menerapkan CompositeCollection.

Menambahkan Lainnya ke DataTemplate

Saat ini data muncul dengan informasi yang diperlukan, tetapi pasti ada ruang untuk perbaikan. Mari kita tingkatkan presentasi dengan menambahkan Border, , Griddan beberapa TextBlock elemen yang menjelaskan data yang sedang ditampilkan.


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

Cuplikan ListBox layar berikut menunjukkan dengan yang dimodifikasi DataTemplateini :

Screenshot of the Introduction to Data Templating Sample window showing the My Task List ListBox with the modified DataTemplate.

Kita dapat mengatur HorizontalContentAlignment ke Stretch pada ListBox untuk memastikan lebar item mengambil seluruh ruang:

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

Dengan properti diatur HorizontalContentAlignment ke Stretch, ListBox sekarang terlihat seperti ini:

Screenshot of the Introduction to Data Templating Sample window showing the My Task List ListBox stretched to fit the screen horizontally.

Menggunakan DataTriggers untuk Menerapkan Nilai Properti

Presentasi saat ini tidak memberi tahu kami apakah merupakan Task tugas rumah atau tugas kantor. Ingatlah bahwa Task objek memiliki TaskType properti jenis TaskType, yang merupakan enumerasi dengan nilai Home dan Work.

Dalam contoh berikut, DataTrigger mengatur BorderBrush elemen border bernama ke Yellow jika TaskType properti adalah 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>

Aplikasi kami sekarang terlihat seperti berikut ini. Tugas beranda muncul dengan batas kuning dan tugas kantor muncul dengan batas aqua:

Screenshot of the Introduction to Data Templating Sample window showing the My Task List ListBox with the home and office task borders highlighted in color.

Dalam contoh DataTrigger ini, menggunakan Setter untuk mengatur nilai properti. Kelas pemicu juga memiliki EnterActions properti dan ExitActions yang memungkinkan Anda memulai serangkaian tindakan seperti animasi. Selain itu, ada juga MultiDataTrigger kelas yang memungkinkan Anda menerapkan perubahan berdasarkan beberapa nilai properti terikat data.

Cara alternatif untuk mencapai efek yang sama adalah dengan mengikat BorderBrush properti ke TaskType properti dan menggunakan pengonversi nilai untuk mengembalikan warna berdasarkan TaskType nilai. Membuat efek di atas menggunakan pengonversi sedikit lebih efisien dalam hal performa. Selain itu, membuat konverter Anda sendiri memberi Anda lebih banyak fleksibilitas karena Anda menyediakan logika Anda sendiri. Pada akhirnya, teknik mana yang Anda pilih tergantung pada skenario dan preferensi Anda. Untuk informasi tentang cara menulis pengonversi, lihat IValueConverter.

Apa yang Termasuk dalam DataTemplate?

Dalam contoh sebelumnya, kami menempatkan pemicu dalam DataTemplate menggunakan DataTemplate.Triggers properti . Pemicu Setter menetapkan nilai properti elemen ( Border elemen) yang berada dalam DataTemplate. Namun, jika properti yang Anda Setters khawatirkan bukan properti elemen yang berada dalam saat ini DataTemplate, mungkin lebih cocok untuk mengatur properti menggunakan Style yang untuk ListBoxItem kelas (jika kontrol yang Anda ikat adalah ListBox). Misalnya, jika Anda ingin menganimasikan TriggerOpacity nilai item saat mouse menunjuk ke item, Anda menentukan pemicu dalam ListBoxItem gaya. Misalnya, lihat Pengenalan Gaya dan Sampel Templat.

Secara umum, perlu diingat bahwa DataTemplate sedang diterapkan ke masing-masing yang dihasilkan ListBoxItem (untuk informasi selengkapnya tentang bagaimana dan di mana sebenarnya diterapkan, lihat ItemTemplate halaman.). Anda DataTemplate hanya memperhatikan presentasi dan tampilan objek data. Dalam kebanyakan kasus, semua aspek presentasi lainnya, seperti seperti apa item saat dipilih atau bagaimana ListBox tata letak item, tidak termasuk dalam definisi DataTemplate. Misalnya, lihat bagian Menata dan Membuat Templat ItemControl .

Memilih DataTemplate Berdasarkan Properti Objek Data

Di bagian Properti DataType, kami membahas bahwa Anda dapat menentukan templat data yang berbeda untuk objek data yang berbeda. Itu sangat berguna ketika Anda memiliki CompositeCollection berbagai jenis atau koleksi dengan item dari berbagai jenis. Di bagian Gunakan DataTriggers untuk Menerapkan Nilai Properti, kami telah menunjukkan bahwa jika Anda memiliki kumpulan jenis objek data yang sama, Anda dapat membuat DataTemplate lalu menggunakan pemicu untuk menerapkan perubahan berdasarkan nilai properti setiap objek data. Namun, pemicu memungkinkan Anda menerapkan nilai properti atau memulai animasi tetapi tidak memberi Anda fleksibilitas untuk membangun kembali struktur objek data Anda. Beberapa skenario mungkin mengharuskan Anda membuat yang berbeda DataTemplate untuk objek data dengan jenis yang sama tetapi memiliki properti yang berbeda.

Misalnya, ketika Task objek memiliki Priority nilai 1, Anda mungkin ingin memberikan tampilan yang sama sekali berbeda untuk berfungsi sebagai pemberitahuan untuk diri Anda sendiri. Dalam hal ini, Anda membuat DataTemplate untuk tampilan objek berprioritas Task tinggi. Mari kita tambahkan yang berikut ini DataTemplate ke bagian sumber daya:

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

Contoh ini menggunakan properti DataTemplate.Resources . Sumber daya yang ditentukan di bagian tersebut dibagikan oleh elemen dalam DataTemplate.

Untuk menyediakan logika untuk memilih mana yang DataTemplate akan digunakan berdasarkan Priority nilai objek data, buat subkelas DataTemplateSelector dan ambil alih SelectTemplate metode . Dalam contoh berikut, SelectTemplate metode ini menyediakan logika untuk mengembalikan templat yang sesuai berdasarkan nilai Priority properti. Templat yang akan dikembalikan ditemukan di sumber daya elemen amplop Window .

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

Kita kemudian dapat mendeklarasikan TaskListDataTemplateSelector sebagai sumber daya:

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

Untuk menggunakan sumber daya pemilih templat, tetapkan ke ItemTemplateSelector properti .ListBox Memanggil ListBox metode TaskListDataTemplateSelector untuk setiap item dalam koleksi yang mendasarSelectTemplate. Panggilan meneruskan objek data sebagai parameter item. DataTemplate yang dikembalikan oleh metode kemudian diterapkan ke objek data tersebut.

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

Dengan pemilih templat di tempat, ListBox sekarang muncul sebagai berikut:

Screenshot of Introduction to Data Templating Sample window showing the My Task List ListBox with the Priority 1 tasks prominently displayed with a red border.

Ini menyimpulkan diskusi kami tentang contoh ini. Untuk sampel lengkapnya, lihat Pengenalan Sampel Templat Data.

Menata dan Membuat Templat ItemControl

Meskipun bukan satu-satunya ItemsControl jenis kontrol yang dapat Anda gunakan DataTemplate dengan, ini adalah skenario yang sangat umum untuk mengikat ItemsControl ke koleksi. Di bagian Apa yang Termasuk dalam DataTemplate , kami membahas bahwa definisi Anda DataTemplate hanya perlu memperhatikan presentasi data. Untuk mengetahui kapan tidak cocok untuk menggunakan DataTemplate , penting untuk memahami berbagai gaya dan properti templat yang disediakan oleh ItemsControl. Contoh berikut dirancang untuk mengilustrasikan fungsi masing-masing properti ini. ItemsControl Dalam contoh ini terikat ke koleksi yang sama Tasks seperti dalam contoh sebelumnya. Untuk tujuan demonstrasi, gaya dan templat dalam contoh ini semuanya dinyatakan sebaris.

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

Berikut ini adalah cuplikan layar contoh saat dirender:

ItemsControl example screenshot

Perhatikan bahwa alih-alih menggunakan ItemTemplate, Anda dapat menggunakan ItemTemplateSelector. Lihat bagian sebelumnya untuk contoh. Demikian pula, alih-alih menggunakan ItemContainerStyle, Anda memiliki opsi untuk menggunakan ItemContainerStyleSelector.

Dua properti terkait gaya lainnya yang ItemsControl tidak ditampilkan di sini adalah GroupStyle dan GroupStyleSelector.

Dukungan untuk Data Hierarkis

Sejauh ini kami hanya melihat cara mengikat dan menampilkan satu koleksi. Terkadang Anda memiliki koleksi yang berisi koleksi lain. Kelas HierarchicalDataTemplate ini dirancang untuk digunakan dengan HeaderedItemsControl jenis untuk menampilkan data tersebut. Dalam contoh berikut, ListLeagueList adalah daftar League objek. Setiap League objek memiliki Name dan kumpulan Division objek. Masing-masing Division memiliki Name kumpulan Team objek dan , dan setiap Team objek memiliki 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>

Contoh menunjukkan bahwa dengan penggunaan HierarchicalDataTemplate, Anda dapat dengan mudah menampilkan data daftar yang berisi daftar lain. Berikut ini adalah cuplikan layar contoh.

HierarchicalDataTemplate sample screenshot

Baca juga