データ テンプレートの概要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 のスタイルとテンプレートモデルによって提供される多くの機能の1つです。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 StyleDataTemplateなどのオブジェクトを再利用できるようにすることを理解しておくことが重要です。In 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. この例では、オブジェクトのListBox Taskリストにバインドされたがあります。In this example, we have a ListBox that is bound to a list of Task objects. Task オブジェクトには TaskName (string)、Description (string)、Priority (int)、および TaskType 型のプロパティがあり、これは値が HomeWorkEnum です。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. したがって、オブジェクトTaskToStringメソッドをオーバーライドする場合、 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. これを行う1つの方法は、 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内に3つの要素として表示されるように指示しています。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}"/>

はリソースなので、型をDataTemplate受け取るプロパティを持つ他のコントロールで使用できるようになりました。 myTaskTemplateBecause myTaskTemplate is a resource, you can now use it on other controls that have a property that takes a DataTemplate type. 上に示すようにItemsControl 、などのオブジェクトListBoxについては、 ItemTemplateプロパティが使用されます。As 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

クラスには、 DataType クラスStyleのプロパティと非常によく似たプロパティがあります。 TargetType 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. DataTemplateしたがって、このx:Key値を割り当てた場合、暗黙的x:KeyなをオーバーライドすることDataTemplateになり、は自動的には適用されません。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 のコレクションDataTemplateにバインドする場合、は上記のを自動的には使用しません。 ContentControlIf 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 / ContentControl Path型の選択を追跡している場合は、バインディングのプロパティを "" に設定して、現在の項目に関心があることを示すことができます。 ItemsControlIf 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.

プロパティは、 CompositeCollectionさまざまな種類のデータオブジェクトがある場合に特に便利です。 DataTypeThe 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. 表示されるデータを記述するBorder Grid、、、およびTextBlock要素を追加して、プレゼンテーションを改良してみましょう。Let'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 オブジェクトには TaskType 型の TaskType プロパティがあり、これは値が HomeWork の列挙であることを思い出してください。Remember that the Task object has a TaskType property of type TaskType, which is an enumeration with values Home and Work.

次の例では、 DataTrigger TaskTypeプロパティがBorderBrush border Yellow の場合、はという名前の要素のをに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

この例ではDataTrigger 、をSetter使用してプロパティ値を設定します。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. [ DataTriggers を使用してプロパティ値を適用する] セクションでは、同じ型のデータオブジェクトのコレクションがある場合に、を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. Resources セクションに次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.

データオブジェクトのPriority値に基づいDataTemplateて使用するロジックを指定するには、の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

は、 DataTemplateと共に使用できる唯一のコントロール型でItemsControl はありませんが、をコレクションにバインドするのは非常に一般的なシナリオです。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. System.windows.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. 同様に、を使用するItemContainerStyle代わりに、をItemContainerStyleSelector使用するオプションもあります。Similarly, instead of using the ItemContainerStyle, you have the option to use the ItemContainerStyleSelector.

ここでは示されていないItemsControlの2つのスタイル関連GroupStyleGroupStyleSelectorプロパティは、とです。Two other style-related properties of the ItemsControl that are not shown here are GroupStyle and GroupStyleSelector.

階層データのサポートSupport for Hierarchical Data

これまでは、1 つのコレクションにバインドして表示する方法のみを説明してきました。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 オブジェクトには、Name と、Division オブジェクトのコレクションがあります。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