데이터 템플릿 개요

WPF 데이터 템플릿 모델을 사용하면 데이터 표시를 매우 유연하게 정의할 수 있습니다. WPF 컨트롤에는 데이터 표시의 사용자 지정을 지원하는 기본 제공 기능이 있습니다. 이 항목에서는 먼저를 정의한 DataTemplate 다음 사용자 지정 논리를 기반으로 템플릿 선택, 계층적 데이터 표시에 대 한 지원 등의 기타 데이터 템플릿 기능을 소개 하는 방법을 보여 줍니다.

사전 요구 사항

이 항목에서는 데이터 템플릿 기능을 집중적으로 살펴보고 데이터 바인딩 개념은 소개하지 않습니다. 기본 데이터 바인딩 개념에 대한 자세한 내용은 데이터 바인딩 개요를 참조하세요.

DataTemplate 는 데이터의 표시에 대 한 것 이며 WPF 스타일 지정 및 템플릿 모델에서 제공 하는 다양 한 기능 중 하나입니다. 을 사용 하 여 컨트롤에 대 한 속성을 설정 하는 방법과 같은 WPF 스타일 지정 및 템플릿 모델에 대 한 소개는 Style 스타일 지정 및 템플릿 항목을 참조 하세요.

또한, 및와 같은 개체를 다시 사용할 수 있도록 하는 것을 이해 하는 것이 중요 Resources Style DataTemplate 합니다. 리소스에 대한 자세한 내용은 XAML 리소스를 참조하세요.

데이터 템플릿 기본 사항

가 중요 한 이유를 보여 주기 위해 DataTemplate 데이터 바인딩 예제를 살펴보겠습니다. 이 예제에서는 ListBox 개체 목록에 바인딩된가 있습니다 Task . 각 Task 개체에는 TaskName(string), Description(string), Priority(int)와 함께 값이 HomeWorkEnum을 나타내는 TaskType 형식 속성이 있습니다.

<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 사용 안 함

가 없으면 DataTemplate 현재는 ListBox 다음과 같습니다.

데이터 템플릿 샘플 스크린샷

특정 지침이 없으면 ListBox 기본적으로 ToString 컬렉션의 개체를 표시 하려고 할 때가 호출 됩니다. 따라서 개체가 메서드를 재정의 하는 경우 Task ToStringListBox 기본 컬렉션에 있는 각 소스 개체의 문자열 표현을 표시 합니다.

예를 들어 Task 클래스가 이 방식으로 ToString 메서드를 재정의하면 nameTaskName 속성에 대한 필드입니다.

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

그러면는 ListBox 다음과 같습니다.

데이터 템플릿 샘플 스크린샷

하지만 이 방법은 제한적이고 유연하지 않습니다. 또한 XML 데이터에 바인딩하는 경우에는를 재정의할 수 없습니다 ToString .

간단한 DataTemplate 정의

이 솔루션은을 정의 하는 것입니다 DataTemplate . 이 작업을 수행 하는 한 가지 방법은의 속성을로 설정 하는 것입니다 ItemTemplate ListBox DataTemplate . 에서 지정 하는 항목 DataTemplate 은 데이터 개체의 시각적 구조가 됩니다. 다음은 DataTemplate 매우 간단 합니다. 각 항목이 내에 세 개의 요소로 표시 되는 지침을 제공 TextBlock StackPanel 합니다. 각 TextBlock 요소는 클래스의 속성에 바인딩됩니다 Task .

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

이 항목의 예제에 대 한 기본 데이터는 CLR 개체의 컬렉션입니다. XML 데이터에 바인딩하는 경우 기본 개념은 동일 하지만 약간의 구문상 차이가 있습니다. 예를 들어를로 설정 하는 대신를 Path=TaskName XPath 로 설정 @TaskName TaskName 합니다 .이 XML 노드의 특성인 경우입니다.

이제 ListBox 는 다음과 같습니다.

데이터 템플릿 샘플 스크린샷

DataTemplate을 리소스로 만들기

위의 예제에서는 인라인을 정의 했습니다 DataTemplate . 더 일반적인 방법은 다음 예제와 같이 재사용 가능한 개체가 될 수 있도록 리소스 섹션에서 데이터 템플릿을 정의하는 것입니다.

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

이제 다음 예제와 같이 myTaskTemplate을 리소스로 사용할 수 있습니다.

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

myTaskTemplate는 리소스 이므로 이제 형식을 사용 하는 속성을 가진 다른 컨트롤에서 사용할 수 있습니다 DataTemplate . 위와 같이 개체의 경우에는 ItemsControl ListBox 속성입니다 ItemTemplate . 개체의 경우 ContentControl ContentTemplate 속성입니다.

DataType 속성

클래스에는 DataTemplate DataType TargetType 클래스의 속성과 매우 유사한 속성이 있습니다 Style . 따라서 위의 예제에서에 대해를 지정 하는 대신 x:Key DataTemplate 다음을 수행할 수 있습니다.

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

이는 DataTemplate 모든 개체에 자동으로 적용 Task 됩니다. 이 경우 x:Key는 암시적으로 설정됩니다. 따라서이 값을 할당 하는 경우 DataTemplate x:Key 암시적인를 재정의 하 고가 x:Key DataTemplate 자동으로 적용 되지 않습니다.

ContentControl개체의 컬렉션에를 바인딩하는 경우 Task 는 위의을 ContentControl 자동으로 사용 하지 않습니다 DataTemplate . 이는에 대 한 바인딩에서 ContentControl 전체 컬렉션 또는 개별 개체를 바인딩할 지 여부를 구분 하기 위해 더 많은 정보를 요구 하기 때문입니다. 에서 ContentControl 특정 형식의 선택 항목을 추적 하는 경우 ItemsControl Path ContentControl / 현재 항목에 관심이 있음을 나타내기 위해 바인딩의 속성을 ""로 설정할 수 있습니다. 예제를 보려면 선택에 따라 수집 및 표시 정보에 바인딩을 참조하세요. 그렇지 않으면 속성을 설정 하 여을 명시적으로 지정 해야 합니다 DataTemplate ContentTemplate .

DataType속성은 CompositeCollection 데이터 개체의 형식이 서로 다른 경우에 특히 유용 합니다. 예제를 보려면 CompositeCollection 구현을 참조하세요.

DataTemplate에 자세히 추가

현재 데이터에는 필요한 정보가 함께 표시되지만 분명히 개선의 여지가 있습니다. Border, Grid 및 표시 되는 데이터를 설명 하는 몇 가지 요소를 추가 하 여 프레젠테이션을 살펴보겠습니다 TextBlock .


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

다음 스크린샷은 ListBox 이 수정 된을 보여 줍니다 DataTemplate .

데이터 템플릿 샘플 스크린샷

에서 HorizontalContentAlignment 을로 설정 Stretch 하 여 ListBox 항목의 너비가 전체 공간을 차지 하는지 확인할 수 있습니다.

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

HorizontalContentAlignment속성이로 설정 된 경우 Stretch 이제는 ListBox 다음과 같습니다.

데이터 템플릿 샘플 스크린샷

DataTrigger를 사용하여 속성 값 적용

현재 표시로는 Task가 홈 작업 또는 사무실 작업인지 알 수 없습니다. 다시 말하지만, Task 개체에는 값이 HomeWork인 열거형을 나타내는 TaskType 형식의 TaskType 속성이 있습니다.

다음 예제에서는 DataTrigger BorderBrush border Yellow 속성이 인 경우 요소의을로 설정 합니다 TaskType 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>

이제 애플리케이션은 다음과 같이 표시됩니다. 홈 작업에는 노란색 테두리가 표시되고 사무실 작업에는 바다색 테두리가 표시됩니다.

데이터 템플릿 샘플 스크린샷

이 예제에서는를 사용 하 여 DataTrigger Setter 속성 값을 설정 합니다. 트리거 클래스에는 EnterActions ExitActions 애니메이션과 같은 작업 집합을 시작할 수 있는 및 속성도 있습니다. 또한 MultiDataTrigger 여러 데이터 바인딩된 속성 값에 따라 변경 내용을 적용할 수 있는 클래스도 있습니다.

동일한 효과를 얻는 또 다른 방법은 속성 BorderBrush 을 속성에 바인딩하고 TaskType 값 변환기를 사용 하 여 값을 기준으로 색을 반환 하는 것입니다 TaskType . 변환기를 사용하여 위 효과를 만드는 방법이 성능 면에서 약간 더 효율적입니다. 또한 자체 변환기를 만들면 자체 논리를 제공할 수 있으므로 더 유연하게 작업할 수 있습니다. 결국 선택하는 방법은 시나리오와 기본 설정에 따라 결정됩니다. 변환기를 작성 하는 방법에 대 한 자세한 내용은을 참조 하십시오 IValueConverter .

DataTemplate은 무엇으로 구성되나요?

이전 예제에서는 속성을 사용 하 여 내에 트리거를 배치 했습니다 DataTemplate DataTemplate.Triggers . Setter트리거의는 내에 있는 요소 (요소)의 속성 값을 설정 합니다 Border DataTemplate . 그러나가 관련 된 속성이 Setters 현재 내에 있는 요소의 속성이 아닌 경우에는 DataTemplate 클래스에 대 한를 사용 하 여 속성을 설정 하는 것이 더 적합할 수 있습니다 Style ListBoxItem (바인딩할 컨트롤이 인 경우 ListBox ). 예를 들어 Trigger Opacity 마우스로 항목을 가리킬 때 항목의 값에 애니메이션 효과를 주려면 스타일 내에서 트리거를 정의 합니다 ListBoxItem . 예제를 보려면 Introduction to Styling and Templating Sample(스타일 지정 및 템플릿 샘플 소개)을 참조하세요.

일반적으로는 DataTemplate 생성 된 각에 적용 됩니다 ListBoxItem . 실제로 적용 되는 방법과 위치에 대 한 자세한 내용은 페이지를 참조 하십시오 ItemTemplate . 는 DataTemplate 데이터 개체의 표시 및 모양에만 관심이 있습니다. 대부분의 경우 항목을 선택 하거나 항목을 레이아웃 하는 방법 등의 다른 모든 측면은 ListBox 의 정의에 속하지 않습니다 DataTemplate . 예제를 보려면 ItemsControl 스타일 지정 및 템플릿 만들기 섹션을 참조하세요.

데이터 개체의 속성에 따라 DataTemplate 선택

DataType 속성 섹션에서 다양한 데이터 개체에 대한 서로 다른 데이터 템플릿을 정의할 수 있음을 설명했습니다. 이는 다양 한 형식의 항목이 나 다른 형식의 항목이 있는 경우 특히 유용 CompositeCollection 합니다. Datatrigger를 사용 하 여 속성 값 적용 섹션에서 동일한 유형의 데이터 개체 컬렉션이 있는 경우를 만든 DataTemplate 다음 트리거를 사용 하 여 각 데이터 개체의 속성 값에 따라 변경 내용을 적용할 수 있습니다. 그러나 트리거를 사용하여 속성 값을 적용하거나 애니메이션을 시작할 수 있지만 트리거는 데이터 개체의 구조를 재구성할 수 있는 유연성이 없습니다. 일부 시나리오에서는 DataTemplate 유형이 같지만 속성은 다른 데이터 개체에 대해 다른를 만들어야 할 수 있습니다.

예를 들어 Task 개체의 Priority 값이 1일 경우 스스로 주의할 수 있도록 완전히 다른 모양을 지정해야 할 수 있습니다. 이 경우 DataTemplate 우선 순위가 높은 개체를 표시 하기 위한를 만듭니다 Task . 리소스 섹션에 다음을 추가 해 보겠습니다 DataTemplate .

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

이 예제에서는 DataTemplate 속성을 사용 합니다. 해당 섹션에 정의 된 리소스는 내의 요소에서 공유 됩니다 DataTemplate .

선택 하는 논리를 제공 DataTemplate 에 따라 사용 하는 Priority 값 데이터 개체의 서브 클래스를 만든 DataTemplateSelector 재정의 SelectTemplate 메서드. 다음 예제에서는 SelectTemplate 의 값을 기반으로 적절 한 템플릿을 반환 하는 논리를 제공 하는 메서드는 Priority 속성입니다. 반환할 템플릿은 상위의 리소스에 위치한 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

그런 다음 TaskListDataTemplateSelector를 리소스로 선언할 수 있습니다.

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

템플릿 선택기 리소스를 사용 하려면 할당에 ItemTemplateSelector 의 속성을 ListBox. ListBox 호출을 SelectTemplate 메서드의 TaskListDataTemplateSelector 각 내부 컬렉션에서 항목에 대 한 합니다. 이 호출은 데이터 개체를 항목 매개 변수로 전달합니다. DataTemplate 에서 반환 하는 메서드가 데이터 개체에 적용 됩니다.

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

템플릿 선택기를 사용 하면 이제이 다음과 같이 ListBox 표시 됩니다.

데이터 템플릿 샘플 스크린샷

이것으로 이 예제에 대한 설명을 마칩니다. 전체 샘플을 보려면 Introduction to Data Templating Sample(데이터 템플릿 샘플 소개)을 참조하세요.

ItemsControl 스타일 지정 및 템플릿 만들기

ItemsControl가와 함께 사용할 수 있는 유일한 컨트롤 형식이 아닌 경우에도를 DataTemplate 컬렉션에 바인딩하는 것이 매우 일반적인 시나리오입니다 ItemsControl . DataTemplate 섹션에서의 정의는 데이터 표시에만 관심이 있다고 설명 했습니다 DataTemplate . 를 사용 하는 데 적합 하지 않은 것을 확인 하려면에서 DataTemplate 제공 하는 다양 한 스타일 및 템플릿 속성을 이해 하는 것이 중요 합니다 ItemsControl . 다음 예제는 이러한 각 속성의 기능을 설명하도록 디자인되어 있습니다. ItemsControl이 예제의는 Tasks 이전 예제와 동일한 컬렉션에 바인딩됩니다. 설명을 위해 이 예제의 스타일 및 템플릿은 모두 인라인으로 선언됩니다.

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

렌더링될 때 예제의 스크린샷은 다음과 같습니다.

ItemsControl 예제 스크린샷

를 사용 하는 대신을 ItemTemplate 사용할 수 있습니다 ItemTemplateSelector . 예제를 보려면 이전 섹션을 참조하세요. 마찬가지로를 사용 하는 대신를 ItemContainerStyle 사용 하는 옵션이 있습니다 ItemContainerStyleSelector .

여기에 표시 되지 않은의 다른 두 가지 스타일 관련 속성 ItemsControlGroupStyleGroupStyleSelector 입니다.

계층적 데이터 지원

지금까지는 단일 컬렉션에 바인딩하고 단일 컬렉션을 표시하는 방법만 살펴봤습니다. 경우에 따라 다른 컬렉션이 포함된 컬렉션이 있을 수 있습니다. HierarchicalDataTemplate클래스는 HeaderedItemsControl 이러한 데이터를 표시 하기 위해 형식과 함께 사용 하도록 설계 되었습니다. 다음 예제에서 ListLeagueListLeague 개체 목록입니다. 각 League 개체에는 NameDivision 개체 컬렉션이 포함됩니다. 각 Division 에는 NameTeam 개체 컬렉션이 포함되고 각 Team 개체에는 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>

이 예제에서는 사용 하 여 보여 줍니다 HierarchicalDataTemplate, 다른 목록이 포함 된 목록 데이터를 쉽게 표시할 수 있습니다. 예제 스크린샷은 다음과 같습니다.

HierarchicalDataTemplate 샘플 스크린 샷

참고 항목