WPF 데이터 템플릿 모델을 사용하면 데이터 표시를 매우 유연하게 정의할 수 있습니다. WPF 컨트롤에는 데이터 표시의 사용자 지정을 지원하는 기본 제공 기능이 있습니다. 이 항목에서는 먼저 DataTemplate를 정의하는 방법을 설명한 다음, 사용자 지정 논리에 따른 템플릿 선택 및 계층적 데이터 표시 지원과 같은 기타 데이터 템플릿 기능을 소개합니다.
필수 조건
이 항목에서는 데이터 템플릿 기능을 집중적으로 살펴보고 데이터 바인딩 개념은 소개하지 않습니다. 기본 데이터 바인딩 개념에 대한 자세한 내용은 데이터 바인딩 개요를 참조하세요.
DataTemplate은 데이터 표현에 관한 것이며, WPF 스타일 및 템플릿 모델에서 제공하는 여러 기능 중 하나입니다. WPF 스타일 및 템플릿 모델, 예를 들어 Style을 사용하여 컨트롤의 속성을 설정하는 방법에 대한 소개는 스타일 지정 및 템플릿 항목을 참조하세요.
또한 Resources를 이해하는 것이 중요하며, 이는 Style 및 DataTemplate와 같은 개체를 재사용 가능하게 하는 기본 요소입니다. 리소스에 대한 자세한 내용은 XAML 리소스를 참조하세요.
데이터 템플릿 기본 사항
DataTemplate이 중요한 이유를 설명하기 위해, 데이터 바인딩 예제를 단계별로 분석해보겠습니다. 이 예제에는 ListBox가 Task 개체 목록에 바인딩되어 있습니다. 각 Task 개체에는 TaskName(string), Description(string), Priority(int) 속성과 TaskType 형식의 속성이 있으며, 이는 Home 및 Work 값을 가진 Enum입니다.
<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는 현재 다음과 같습니다.
&각 소스 개체에 대한 SDKSample.Task 문자열 표현을 표시하는 내 작업 목록 ListBox를 보여주는 데이터 템플릿 샘플 소개 창의 스크린샷,DataTemplatingIntro_fig1
구체적인 명령 없이 컬렉션의 객체를 표시하려고 할 때, 기본적으로 ListBox가 ToString을 호출합니다. 따라서 Task 개체가 ToString 메서드를 재정의할 경우 ListBox는 기본 컬렉션에 있는 각 소스 개체의 문자열 표현을 표시합니다.
예를 들어, Task 클래스가 이 방식으로 ToString 메서드를 재정의하면 name는 TaskName 속성에 대한 필드입니다.
public override string ToString()
{
return name.ToString();
}
Public Overrides Function ToString() As String
Return _name.ToString()
End Function
그러면 ListBox 는 다음과 같습니다.
데이터 템플릿 샘플 소개 창의 스크린샷으로, My Task List ListBox에 작업 목록이 표시되어 있습니다. DataTemplatingIntro_fig2
하지만 이 방법은 제한적이고 유연하지 않습니다. 또한 XML 데이터에 바인딩할 경우 ToString을 오버라이드할 수 없습니다.
간단한 DataTemplate 정의
해결 방법은 DataTemplate을 정의하는 것입니다. 이 작업을 수행하는 한 가지 방법은 ListBox의 ItemTemplate 속성을 DataTemplate으로 설정하는 것입니다.
DataTemplate에 지정한 내용이 데이터 객체의 시각적 구조가 됩니다. 다음 DataTemplate은 상당히 간단합니다. 각 항목이 StackPanel 내에서 TextBlock 요소 세 개로 표시되도록 지침을 제공하고 있습니다. 각 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 속성이 있으며, 이는 Style 클래스의 TargetType 속성과 비슷합니다. 따라서 위 예제에서 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에 대한 바인딩에는 전체 컬렉션에 바인딩할지 아니면 개별 객체에 바인딩할지를 구분하기 위한 추가 정보가 필요하기 때문입니다. 컨트롤의 ItemsControl 형식의 선택 항목을 추적하는 경우, ContentControl 바인딩의 Path 속성을 "/"로 설정하여 현재 항목에 관심이 있음을 나타낼 수 있습니다. 예를 보려면 컬렉션에 바인딩하고 선택에 따라 정보를 표시하는 방법을 참조하세요. 그렇지 않으면 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를 보여줍니다.

ListBox에서 HorizontalContentAlignment를 Stretch로 설정하면 항목의 너비가 전체 공간을 차지하도록 할 수 있습니다.
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplate="{StaticResource myTaskTemplate}"
HorizontalContentAlignment="Stretch"/>
`HorizontalContentAlignment 속성을 Stretch로 설정하면 ListBox는 이제 다음과 같이 보입니다.`
DataTrigger를 사용하여 속성 값 적용
현재 프레젠테이션으로는 Task가 홈 작업인지 또는 사무실 작업인지 알 수 없습니다. 기억하세요, Task 객체에는 TaskType 형식의 TaskType 속성이 있으며, 이는 Home 및 Work 값을 가지는 열거형입니다.
다음 예제에서 DataTrigger는 TaskType 속성이 TaskType.Home인 경우 border라는 요소의 BorderBrush을 Yellow로 설정합니다.
<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>
이제 애플리케이션은 다음과 같이 표시됩니다. 홈 작업에는 노란색 테두리가 표시되고 사무실 작업에는 바다색 테두리가 표시됩니다.
가정 및 업무 작업 경계가 색으로 강조 표시된 내 작업 목록 ListBox를 보여주는 데이터 템플릿 소개 샘플 창의 스크린샷입니다. DataTemplatingIntro_fig6
이 예제에서 DataTrigger는 Setter를 사용하여 속성 값을 설정합니다. 트리거 클래스에는 EnterActions 및 ExitActions 속성이 있어 애니메이션과 같은 일련의 작업을 시작할 수 있습니다. 또한 여러 데이터 바인딩 속성 값에 따라 변경 내용을 적용할 수 있는 MultiDataTrigger 클래스가 있습니다.
같은 효과를 얻기 위한 대체 방법은 BorderBrush 속성을 TaskType 속성에 바인딩하고, 값 변환기를 사용하여 TaskType 값에 따라 색상을 반환하는 것입니다. 변환기를 사용하여 위 효과를 만드는 방법이 성능 면에서 약간 더 효율적입니다. 또한 자체 변환기를 만들면 자체 논리를 제공할 수 있으므로 더 유연하게 작업할 수 있습니다. 결국 선택하는 방법은 시나리오와 기본 설정에 따라 결정됩니다. 변환기를 작성하는 방법에 대한 자세한 내용은 IValueConverter를 참조하세요.
DataTemplate은 무엇으로 구성되나요?
이전 예제에서는 DataTemplate 내에 트리거를 DataTemplate.Triggers 속성을 사용하여 배치했습니다. 트리거의 Setter는 DataTemplate 내에 있는 Border 요소(예: Border 요소)의 속성 값을 설정합니다. 하지만, 속성들이 DataTemplate 내의 요소가 아닌 Setters와 관련된 경우에는, 해당 속성을 설정하려면 ListBox을(를) 사용하는 컨트롤이 ListBoxItem 클래스에 해당할 때 Style을(를) 사용하는 것이 더 적절할 수 있습니다. 예를 들어,Trigger를 사용하여 마우스가 항목을 가리킬 때 Opacity 값에 대해 애니메이션 효과를 주려면 ListBoxItem 스타일 내에서 트리거를 정의해야 합니다. 예제를 보려면 스타일 지정 및 템플릿 소개 샘플 (Introduction to Styling and Templating Sample)을 참조하세요.
일반적으로 DataTemplate는 생성된 각 ListBoxItem에 적용된다는 것을 기억하세요(실제로 ItemTemplate 페이지에서 어떻게 그리고 어디에 적용되는지에 대한 자세한 정보를 참조하세요). DataTemplate은 데이터 객체의 표시와 외형에만 관련이 있습니다. 대부분의 경우 항목이 선택될 때 그 항목이 어떻게 보이는지 또는 ListBox가 항목을 어떻게 배치하는지 등의 기타 모든 표시 사항은 DataTemplate의 정의에 포함되지 않습니다. 예제를 보려면 ItemsControl 스타일 및 템플릿 섹션을 참조하세요.
데이터 개체의 속성에 따라 DataTemplate 선택
DataType 속성 섹션에서 다양한 데이터 개체에 대해 다른 데이터 템플릿을 정의할 수 있음을 설명했습니다. 이 기능은 다양한 형식 또는 다양한 형식의 항목이 포함된 컬렉션을 사용할 때 특히 유용합니다. 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.Resources 속성을 사용합니다. 해당 섹션에 정의된 리소스는 DataTemplate 내부의 요소에서 공유됩니다.
데이터 개체의 Priority 값을 기준으로 사용할 DataTemplate를 선택하는 논리를 제공하기 위해, DataTemplateSelector의 서브클래스를 만들고 SelectTemplate 메서드를 재정의하십시오. 다음 예제에서는 Priority 속성의 값에 따라 적절한 템플릿을 반환하는 논리를 제공하는 메서드인 SelectTemplate 메서드를 설명합니다. 반환할 템플릿은 포괄하는 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는 기본 컬렉션의 각 항목에 대해 TaskListDataTemplateSelector의 SelectTemplate 메서드를 호출합니다. 이 호출은 데이터 개체를 항목 매개 변수로 전달합니다. 메서드에 의해 반환된 DataTemplate가 데이터 객체에 적용됩니다.
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
HorizontalContentAlignment="Stretch"/>
템플릿 선택기를 배치하면 이제 ListBox가 다음과 같이 표시됩니다.
이것으로 이 예제에 대한 설명을 마칩니다. 전체 샘플을 보려면 데이터 템플릿 샘플 소개를 참조하세요.
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 예제 스크린샷 DataBinding_ItemsControlProperties
여기에 표시되지 않은 ItemsControl의 다른 두 가지 스타일 관련 속성은 GroupStyle 및 GroupStyleSelector입니다.
계층적 데이터 지원
지금까지는 단일 컬렉션에 바인딩하고 단일 컬렉션을 표시하는 방법만 살펴봤습니다. 경우에 따라 다른 컬렉션이 포함된 컬렉션이 있을 수 있습니다. `HierarchicalDataTemplate` 클래스는 이러한 데이터를 표시하는 `HeaderedItemsControl` 형식과 함께 사용하도록 설계되었습니다. 다음 예제에서 ListLeagueList는 League 개체 목록입니다. 각 League 개체는 Name 개체와 Division 개체들로 이루어집니다. 각 Division에는 Name 및 Team 객체 컬렉션이 포함되며, 각 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를 사용하여 다른 목록을 포함하는 목록 데이터를 쉽게 표시할 수 있음을 보여줍니다. 예제 스크린샷은 다음과 같습니다.
계층 데이터 템플릿 샘플 스크린샷 데이터 바인딩_계층형 데이터 템플릿
참고하십시오
- 데이터 바인딩
- DataTemplate에서 생성된 요소 찾기
- 스타일링 및 템플링
- 데이터 바인딩 개요
- GridView 열 머리글 스타일 및 템플릿 개요
.NET Desktop feedback