데이터 템플릿 개요Data Templating Overview

WPF 데이터 템플릿 모델을 사용하면 데이터 표시를 매우 유연하게 정의할 수 있습니다.The WPF data templating model provides you with great flexibility to define the presentation of your data. WPF 컨트롤에는 데이터 표시의 사용자 지정을 지원하는 기본 제공 기능이 있습니다.WPF controls have built-in functionality to support the customization of data presentation. 이 항목에서는 먼저를 DataTemplate 정의한 다음 사용자 지정 논리를 기반으로 템플릿 선택, 계층적 데이터 표시에 대 한 지원 등의 기타 데이터 템플릿 기능을 소개 하는 방법을 보여 줍니다.This topic first demonstrates how to define a DataTemplate and then introduces other data templating features, such as the selection of templates based on custom logic and the support for the display of hierarchical data.

전제 조건Prerequisites

이 항목에서는 데이터 템플릿 기능을 집중적으로 살펴보고 데이터 바인딩 개념은 소개하지 않습니다.This topic focuses on data templating features and is not an introduction of data binding concepts. 기본 데이터 바인딩 개념에 대한 자세한 내용은 데이터 바인딩 개요를 참조하세요.For information about basic data binding concepts, see the Data Binding Overview.

DataTemplate는 데이터의 표시에 대 한 것 이며 WPF 스타일 지정 및 템플릿 모델에서 제공 하는 다양 한 기능 중 하나입니다.DataTemplate is about the presentation of data and is one of the many features provided by the WPF styling and templating model. Style 사용 하 여 컨트롤에 대 한 속성을 설정 하는 방법과 같은 WPF 스타일 지정 및 템플릿 모델에 대 한 소개는 스타일 지정 및 템플릿 항목을 참조 하세요.For an introduction of the WPF styling and templating model, such as how to use a Style to set properties on controls, see the Styling and Templating topic.

또한, Resources Style 및 와같은개체를다시사용할수있도록하는것을이해하는것이중요합니다.DataTemplateIn addition, it is important to understand Resources, which are essentially what enable objects such as Style and DataTemplate to be reusable. 리소스에 대한 자세한 내용은 XAML 리소스를 참조하세요.For more information on resources, see XAML Resources.

데이터 템플릿 기본 사항Data Templating Basics

가 중요 한 DataTemplate 이유를 보여 주기 위해 데이터 바인딩 예제를 살펴보겠습니다.To demonstrate why DataTemplate is important, let's walk through a data binding example. 이 예제에서는 Task 개체 목록에 바인딩된 ListBox 가 있습니다.In this example, we have a ListBox that is bound to a list of Task objects. Task 개체에는 TaskName(string), Description(string), Priority(int)와 함께 값이 HomeWorkEnum을 나타내는 TaskType 형식 속성이 있습니다.Each Task object has a TaskName (string), a Description (string), a Priority (int), and a property of type TaskType, which is an Enum with values Home and 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>

DataTemplate 사용 안 함Without a DataTemplate

가 없으면 DataTemplate ListBox 현재는 다음과 같습니다.Without a DataTemplate, our ListBox currently looks like this:

데이터 템플릿 샘플 스크린샷Data templating sample screenshot

특정 지침이 ListBox 없으면 기본적으로 컬렉션의 개체를 표시 하려고 할 때가 ToString 호출 됩니다.What's happening is that without any specific instructions, the ListBox by default calls ToString when trying to display the objects in the collection. 따라서 Task 개체가 ToString 메서드를 재정의 하는 경우는 ListBox 기본 컬렉션에 있는 각 소스 개체의 문자열 표현을 표시 합니다.Therefore, if the Task object overrides the ToString method, then the ListBox displays the string representation of each source object in the underlying collection.

예를 들어 Task 클래스가 이 방식으로 ToString 메서드를 재정의하면 nameTaskName 속성에 대한 필드입니다.For example, if the Task class overrides the ToString method this way, where name is the field for the TaskName property:

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

그러면는 ListBox 다음과 같습니다.Then the ListBox looks like the following:

데이터 템플릿 샘플 스크린샷Data templating sample screenshot

하지만 이 방법은 제한적이고 유연하지 않습니다.However, that is limiting and inflexible. 또한 XMLXML 데이터에 바인딩할 경우 ToString을 재정의할 수 없습니다.Also, if you are binding to XMLXML data, you wouldn't be able to override ToString.

간단한 DataTemplate 정의Defining a Simple DataTemplate

이 솔루션은을 DataTemplate정의 하는 것입니다.The solution is to define a DataTemplate. 이 작업을 수행 하는 한 가지 방법은 ItemTemplate ListBox 의 속성을로 DataTemplate설정 하는 것입니다.One way to do that is to set the ItemTemplate property of the ListBox to a DataTemplate. 에서 지정 하는 항목 DataTemplate 은 데이터 개체의 시각적 구조가 됩니다.What you specify in your DataTemplate becomes the visual structure of your data object. 다음 DataTemplate 은 매우 간단 합니다.The following DataTemplate is fairly simple. 각 항목이 TextBlock StackPanel내에 세 개의 요소로 표시 되는 지침을 제공 합니다.We are giving instructions that each item appears as three TextBlock elements within a StackPanel. TextBlock 요소는 Task 클래스의 속성에 바인딩됩니다.Each TextBlock element is bound to a property of the Task class.

<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 개체의 컬렉션입니다.The underlying data for the examples in this topic is a collection of CLR objects. XMLXML 데이터에 바인딩할 경우 기본 개념은 같지만 약간의 구문적 차이점이 있습니다.If you are binding to XMLXML data, the fundamental concepts are the same, but there is a slight syntactic difference. 예를 들어을 (를 Path=TaskName) 설정 하는 XPath 대신 @TaskName 를로 TaskName 설정 합니다 (가 XMLXML 노드의 특성인 경우).For example, instead of having Path=TaskName, you would set XPath to @TaskName (if TaskName is an attribute of your XMLXML node).

ListBox 이제는 다음과 같습니다.Now our ListBox looks like the following:

데이터 템플릿 샘플 스크린샷Data templating sample screenshot

DataTemplate을 리소스로 만들기Creating the DataTemplate as a Resource

위의 예제에서는 DataTemplate 인라인을 정의 했습니다.In the above example, we defined the DataTemplate inline. 더 일반적인 방법은 다음 예제와 같이 재사용 가능한 개체가 될 수 있도록 리소스 섹션에서 데이터 템플릿을 정의하는 것입니다.It is more common to define it in the resources section so it can be a reusable object, as in the following example:

<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을 리소스로 사용할 수 있습니다.Now you can use myTaskTemplate as a resource, as in the following example:

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

myTaskTemplate 리소스 이므로 이제 DataTemplate 형식을 사용 하는 속성을 가진 다른 컨트롤에서 사용할 수 있습니다.Because myTaskTemplate is a resource, you can now use it on other controls that have a property that takes a DataTemplate type. 위와 같이 개체 ItemsControl ListBox의경우에는 속성입니다.ItemTemplateAs shown above, for ItemsControl objects, such as the ListBox, it is the ItemTemplate property. ContentControl 개체ContentTemplate 의 경우 속성입니다.For ContentControl objects, it is the ContentTemplate property.

DataType 속성The DataType Property

클래스에 TargetType 는 클래스Style 의 속성과 매우 유사한 DataType 속성이 있습니다. DataTemplateThe DataTemplate class has a DataType property that is very similar to the TargetType property of the Style class. 따라서 위의 예제 x:Key DataTemplate 에서에 대해를 지정 하는 대신 다음을 수행할 수 있습니다.Therefore, instead of specifying an x:Key for the DataTemplate in the above example, you can do the following:

<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 개체에 자동으로 적용 됩니다.This DataTemplate gets applied automatically to all Task objects. 이 경우 x:Key는 암시적으로 설정됩니다.Note that in this case the x:Key is set implicitly. 따라서이 할당 하는 경우 DataTemplatex:Key 값을 암시적 재정의 x:KeyDataTemplate 자동으로 적용할 수는 없습니다.Therefore, if you assign this DataTemplate an x:Key value, you are overriding the implicit x:Key and the DataTemplate would not be applied automatically.

ContentControl 개체의 Task 컬렉션에를 바인딩하는 경우는 ContentControl 위의 DataTemplate 을 자동으로 사용 하지 않습니다.If you are binding a ContentControl to a collection of Task objects, the ContentControl does not use the above DataTemplate automatically. 왜냐하면의 바인딩에서 ContentControl 전체 컬렉션 또는 개별 개체에 바인딩할 인지 구분 하기 위해 더 많은 정보가 필요 합니다.This is because the binding on a ContentControl needs more information to distinguish whether you want to bind to an entire collection or the individual objects. 경우에 ContentControl 의 선택 영역 추적는 ItemsControl 형식을 설정할 수 있습니다를 Path 의 속성을 ContentControl 바인딩할 "/" 현재 항목에 관심이 나타내려면.If your ContentControl is tracking the selection of an ItemsControl type, you can set the Path property of the ContentControl binding to "/" to indicate that you are interested in the current item. 예제를 보려면 선택에 따라 수집 및 표시 정보에 바인딩을 참조하세요.For an example, see Bind to a Collection and Display Information Based on Selection. 지정 해야 하는 고, 그렇지 합니다 DataTemplate 명시적으로 설정 하 여는 ContentTemplate 속성입니다.Otherwise, you need to specify the DataTemplate explicitly by setting the ContentTemplate property.

합니다 DataType 속성은 경우에 특히 유용는 CompositeCollection 다양 한 유형의 데이터 개체입니다.The DataType property is particularly useful when you have a CompositeCollection of different types of data objects. 예제를 보려면 CompositeCollection 구현을 참조하세요.For an example, see Implement a CompositeCollection.

DataTemplate에 자세히 추가Adding More to the DataTemplate

현재 데이터에는 필요한 정보가 함께 표시되지만 분명히 개선의 여지가 있습니다.Currently the data appears with the necessary information, but there's definitely room for improvement. , 및 표시 되는 데이터를 설명 하는 몇 가지 TextBlock 요소를 추가 하 여 프레젠테이션을 살펴보겠습니다. Grid BorderLet's improve on the presentation by adding a Border, a Grid, and some TextBlock elements that describe the data that is being displayed.


<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된을 보여 줍니다.The following screenshot shows the ListBox with this modified DataTemplate:

데이터 템플릿 샘플 스크린샷Data templating sample screenshot

에서을로 HorizontalContentAlignment Stretch 설정 하 여 항목의 너비가 전체 공간을 차지 하는지 확인할 수 있습니다. ListBoxWe can set HorizontalContentAlignment to Stretch on the ListBox to make sure the width of the items takes up the entire space:

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

속성이로 Stretch설정 된 경우 이제는 ListBox 다음과 같습니다. HorizontalContentAlignmentWith the HorizontalContentAlignment property set to Stretch, the ListBox now looks like this:

데이터 템플릿 샘플 스크린샷Data templating sample screenshot

DataTrigger를 사용하여 속성 값 적용Use DataTriggers to Apply Property Values

현재 표시로는 Task가 홈 작업 또는 사무실 작업인지 알 수 없습니다.The current presentation does not tell us whether a Task is a home task or an office task. 다시 말하지만, Task 개체에는 값이 HomeWork인 열거형을 나타내는 TaskType 형식의 TaskType 속성이 있습니다.Remember that the Task object has a TaskType property of type TaskType, which is an enumeration with values Home and Work.

다음 예에서 DataTrigger 설정 합니다 BorderBrush 요소의 borderYellow 경우를 TaskType 속성이 TaskType.Home.In the following example, the DataTrigger sets the BorderBrush of the element named border to Yellow if the TaskType property 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>

이제 애플리케이션은 다음과 같이 표시됩니다.Our application now looks like the following. 홈 작업에는 노란색 테두리가 표시되고 사무실 작업에는 바다색 테두리가 표시됩니다.Home tasks appear with a yellow border and office tasks appear with an aqua border:

데이터 템플릿 샘플 스크린샷Data templating sample screenshot

이 예제에서는 DataTriggerSetter 사용 하 여 속성 값을 설정 합니다.In this example the DataTrigger uses a Setter to set a property value. 트리거 클래스 EnterActions 에는 애니메이션과 같은 작업 ExitActions 집합을 시작할 수 있는 및 속성도 있습니다.The trigger classes also have the EnterActions and ExitActions properties that allow you to start a set of actions such as animations. 또한 여러 데이터 바인딩된 속성 값에 MultiDataTrigger 따라 변경 내용을 적용할 수 있는 클래스도 있습니다.In addition, there is also a MultiDataTrigger class that allows you to apply changes based on multiple data-bound property values.

동일한 효과를 얻는 또 다른 방법은 속성 BorderBrush TaskType 을 속성에 바인딩하고 값 변환기를 사용 하 여 TaskType 값을 기준으로 색을 반환 하는 것입니다.An alternative way to achieve the same effect is to bind the BorderBrush property to the TaskType property and use a value converter to return the color based on the TaskType value. 변환기를 사용하여 위 효과를 만드는 방법이 성능 면에서 약간 더 효율적입니다.Creating the above effect using a converter is slightly more efficient in terms of performance. 또한 자체 변환기를 만들면 자체 논리를 제공할 수 있으므로 더 유연하게 작업할 수 있습니다.Additionally, creating your own converter gives you more flexibility because you are supplying your own logic. 결국 선택하는 방법은 시나리오와 기본 설정에 따라 결정됩니다.Ultimately, which technique you choose depends on your scenario and your preference. 변환기를 작성 하는 방법에 대 한 자세한 IValueConverter내용은을 참조 하십시오.For information about how to write a converter, see IValueConverter.

DataTemplate은 무엇으로 구성되나요?What Belongs in a DataTemplate?

이전 예제에서는를 DataTemplate DataTemplate사용 하 여 내에 트리거를 배치 했습니다.TriggersIn the previous example, we placed the trigger within the DataTemplate using the DataTemplate.Triggers 속성의 값에 따라 달라집니다.property. 트리거의 Setter 는 내에 있는 요소 Border (요소 DataTemplate)의 속성 값을 설정 합니다.The Setter of the trigger sets the value of a property of an element (the Border element) that is within the DataTemplate. 그러나가 관련 된 Setters 속성이 현재 DataTemplate내에 있는 요소의 속성이 아닌 경우 ListBoxItem 클래스에 대 한를 Style 사용 하 여 속성을 설정 하는 것이 더 적합할 수 있습니다 (있는 경우). 바인딩하는 컨트롤이입니다 ListBox.However, if the properties that your Setters are concerned with are not properties of elements that are within the current DataTemplate, it may be more suitable to set the properties using a Style that is for the ListBoxItem class (if the control you are binding is a ListBox). 예를 Trigger 들어 마우스로 항목을 가리킬 때 항목의 Opacity 값에 애니메이션 효과를 주려면 ListBoxItem 스타일 내에서 트리거를 정의 합니다.For example, if you want your Trigger to animate the Opacity value of the item when a mouse points to an item, you define triggers within a ListBoxItem style. 예제를 보려면 Introduction to Styling and Templating Sample(스타일 지정 및 템플릿 샘플 소개)을 참조하세요.For an example, see the Introduction to Styling and Templating Sample.

일반적으로는 DataTemplate 생성 ListBoxItem 된 각에 적용 됩니다. ItemTemplate 실제로 적용 되는 방법과 위치에 대 한 자세한 내용은 페이지를 참조 하십시오.In general, keep in mind that the DataTemplate is being applied to each of the generated ListBoxItem (for more information about how and where it is actually applied, see the ItemTemplate page.). DataTemplate 는 데이터 개체의 표시 및 모양에만 관심이 있습니다.Your DataTemplate is concerned with only the presentation and appearance of the data objects. 대부분의 경우 항목을 선택 하거나 항목을 ListBox 레이아웃 하는 방법 등 DataTemplate의 다른 모든 측면은의 정의에 속하지 않습니다.In most cases, all other aspects of presentation, such as what an item looks like when it is selected or how the ListBox lays out the items, do not belong in the definition of a DataTemplate. 예제를 보려면 ItemsControl 스타일 지정 및 템플릿 만들기 섹션을 참조하세요.For an example, see the Styling and Templating an ItemsControl section.

데이터 개체의 속성에 따라 DataTemplate 선택Choosing a DataTemplate Based on Properties of the Data Object

DataType 속성 섹션에서 다양한 데이터 개체에 대한 서로 다른 데이터 템플릿을 정의할 수 있음을 설명했습니다.In The DataType Property section, we discussed that you can define different data templates for different data objects. 이는 다양 한 CompositeCollection 형식의 항목이 나 다른 형식의 항목이 있는 경우 특히 유용 합니다.That is especially useful when you have a CompositeCollection of different types or collections with items of different types. Datatrigger를 사용 하 여 속성 값 적용 섹션에서 동일한 유형의 데이터 개체 컬렉션이 있는 경우를 DataTemplate 만든 다음 트리거를 사용 하 여 각 데이터 개체의 속성 값에 따라 변경 내용을 적용할 수 있습니다.In the Use DataTriggers to Apply Property Values section, we have shown that if you have a collection of the same type of data objects you can create a DataTemplate and then use triggers to apply changes based on the property values of each data object. 그러나 트리거를 사용하여 속성 값을 적용하거나 애니메이션을 시작할 수 있지만 트리거는 데이터 개체의 구조를 재구성할 수 있는 유연성이 없습니다.However, triggers allow you to apply property values or start animations but they don't give you the flexibility to reconstruct the structure of your data objects. 일부 시나리오에서는 유형이 같지만 속성은 다른 데이터 DataTemplate 개체에 대해 다른를 만들어야 할 수 있습니다.Some scenarios may require you to create a different DataTemplate for data objects that are of the same type but have different properties.

예를 들어 Task 개체의 Priority 값이 1일 경우 스스로 주의할 수 있도록 완전히 다른 모양을 지정해야 할 수 있습니다.For example, when a Task object has a Priority value of 1, you may want to give it a completely different look to serve as an alert for yourself. 이 경우 우선 순위가 DataTemplate Task 높은 개체를 표시 하기 위한를 만듭니다.In that case, you create a DataTemplate for the display of the high-priority Task objects. 리소스 섹션에 다음 DataTemplate 을 추가 해 보겠습니다.Let's add the following DataTemplate to the resources section:

<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사용 합니다.ResourcesNotice this example uses the DataTemplate.Resources 속성의 값에 따라 달라집니다.property. 해당 섹션에 정의 된 리소스는 내의 DataTemplate요소에서 공유 됩니다.Resources defined in that section are shared by the elements within the DataTemplate.

선택 하는 논리를 제공 DataTemplate 에 따라 사용 하는 Priority 값 데이터 개체의 서브 클래스를 만든 DataTemplateSelector 재정의 SelectTemplate 메서드.To supply logic to choose which DataTemplate to use based on the Priority value of the data object, create a subclass of DataTemplateSelector and override the SelectTemplate method. 다음 예제에서는 SelectTemplate 의 값을 기반으로 적절 한 템플릿을 반환 하는 논리를 제공 하는 메서드는 Priority 속성입니다.In the following example, the SelectTemplate method provides logic to return the appropriate template based on the value of the Priority property. 반환할 템플릿은 상위의 리소스에 위치한 Window 요소입니다.The template to return is found in the resources of the enveloping 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

그런 다음 TaskListDataTemplateSelector를 리소스로 선언할 수 있습니다.We can then declare the TaskListDataTemplateSelector as a resource:

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

템플릿 선택기 리소스를 사용 하려면 할당에 ItemTemplateSelector 의 속성을 ListBox.To use the template selector resource, assign it to the ItemTemplateSelector property of the ListBox. ListBox 호출을 SelectTemplate 메서드의 TaskListDataTemplateSelector 각 내부 컬렉션에서 항목에 대 한 합니다.The ListBox calls the SelectTemplate method of the TaskListDataTemplateSelector for each of the items in the underlying collection. 이 호출은 데이터 개체를 항목 매개 변수로 전달합니다.The call passes the data object as the item parameter. DataTemplate 에서 반환 하는 메서드가 데이터 개체에 적용 됩니다.The DataTemplate that is returned by the method is then applied to that data object.

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

템플릿 선택기를 사용 하면 ListBox 이제이 다음과 같이 표시 됩니다.With the template selector in place, the ListBox now appears as follows:

데이터 템플릿 샘플 스크린샷Data templating sample screenshot

이것으로 이 예제에 대한 설명을 마칩니다.This concludes our discussion of this example. 전체 샘플을 보려면 Introduction to Data Templating Sample(데이터 템플릿 샘플 소개)을 참조하세요.For the complete sample, see Introduction to Data Templating Sample.

ItemsControl 스타일 지정 및 템플릿 만들기Styling and Templating an ItemsControl

가와 함께 사용할 수 있는 유일한 컨트롤 형식이 아닌 경우에도를 컬렉션 ItemsControl 에 바인딩하는 것이 매우 일반적인 시나리오입니다. DataTemplate ItemsControlEven though the ItemsControl is not the only control type that you can use a DataTemplate with, it is a very common scenario to bind an ItemsControl to a collection. DataTemplate 섹션에서의 DataTemplate 정의는 데이터 표시에만 관심이 있다고 설명 했습니다.In the What Belongs in a DataTemplate section we discussed that the definition of your DataTemplate should only be concerned with the presentation of data. DataTemplate 사용 하는 데 적합 하지 않은 것을 확인 하려면에서 제공 ItemsControl하는 다양 한 스타일 및 템플릿 속성을 이해 하는 것이 중요 합니다.In order to know when it is not suitable to use a DataTemplate it is important to understand the different style and template properties provided by the ItemsControl. 다음 예제는 이러한 각 속성의 기능을 설명하도록 디자인되어 있습니다.The following example is designed to illustrate the function of each of these properties. ItemsControl 예제의는 이전 예제와 동일한 Tasks 컬렉션에 바인딩됩니다.The ItemsControl in this example is bound to the same Tasks collection as in the previous example. 설명을 위해 이 예제의 스타일 및 템플릿은 모두 인라인으로 선언됩니다.For demonstration purposes, the styles and templates in this example are all declared inline.

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

렌더링될 때 예제의 스크린샷은 다음과 같습니다.The following is a screenshot of the example when it is rendered:

ItemsControl 예제 스크린샷ItemsControl example screenshot

를 사용 하 ItemTemplate는 대신을 ItemTemplateSelector사용할 수 있습니다.Note that instead of using the ItemTemplate, you can use the ItemTemplateSelector. 예제를 보려면 이전 섹션을 참조하세요.Refer to the previous section for an example. 마찬가지로를 사용 하는 대신 ItemContainerStyleItemContainerStyleSelector사용 하는 옵션이 있습니다.Similarly, instead of using the ItemContainerStyle, you have the option to use the ItemContainerStyleSelector.

다른 두 스타일 관련 속성을 ItemsControl 다음은 표시 되지 않습니다 하 GroupStyleGroupStyleSelector.Two other style-related properties of the ItemsControl that are not shown here are GroupStyle and GroupStyleSelector.

계층적 데이터 지원Support for Hierarchical Data

지금까지는 단일 컬렉션에 바인딩하고 단일 컬렉션을 표시하는 방법만 살펴봤습니다.So far we have only looked at how to bind to and display a single collection. 경우에 따라 다른 컬렉션이 포함된 컬렉션이 있을 수 있습니다.Sometimes you have a collection that contains other collections. 클래스 HierarchicalDataTemplate 는 이러한 데이터를 표시 하기 위해 HeaderedItemsControl 형식과 함께 사용 하도록 설계 되었습니다.The HierarchicalDataTemplate class is designed to be used with HeaderedItemsControl types to display such data. 다음 예제에서 ListLeagueListLeague 개체 목록입니다.In the following example, ListLeagueList is a list of League objects. League 개체에는 NameDivision 개체 컬렉션이 포함됩니다.Each League object has a Name and a collection of Division objects. Division 에는 NameTeam 개체 컬렉션이 포함되고 각 Team 개체에는 Name이 포함됩니다.Each Division has a Name and a collection of Team objects, and each Team object has a 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, 다른 목록이 포함 된 목록 데이터를 쉽게 표시할 수 있습니다.The example shows that with the use of HierarchicalDataTemplate, you can easily display list data that contains other lists. 예제 스크린샷은 다음과 같습니다.The following is a screenshot of the example.

HierarchicalDataTemplate 샘플 스크린 샷HierarchicalDataTemplate sample screenshot

참고자료See also