Übersicht über Datenvorlagen
Das WPF-Daten templating-Modell bietet Ihnen eine große Flexibilität, um die Darstellung Ihrer Daten zu definieren. WPF-Steuerelemente verfügen über integrierte Funktionen zur Unterstützung der Anpassung der Datenpräsentation. In diesem Thema wird zuerst erläutert, wie man ein DataTemplate definiert, und dann weitere Funktionen von Datentemplates vorgestellt, wie z. B. die Auswahl von Vorlagen basierend auf benutzerdefinierter Logik und die Unterstützung für die Anzeige hierarchischer Daten.
Voraussetzungen
Dieses Thema konzentriert sich auf Datentemplating-Funktionen und ist keine Einführung in Datenbindungskonzepte. Informationen zu grundlegenden Datenbindungskonzepten finden Sie in der Data Binding Overview.
Bei DataTemplate handelt es sich um die Präsentation von Daten. Diese ist eines der vielen Merkmale, die vom Styling- und Vorlagenmodell von WPF bereitgestellt werden. Eine Einführung in das Formatierungs- und Vorlagenerstellungsmodell von WPF, z. B. in die Verwendung von Style zur Festlegung von Eigenschaften in Steuerelementen, finden Sie im Thema Erstellen von Formaten und Vorlagen.
Darüber hinaus ist es wichtig, Resources
zu verstehen, die es im Wesentlichen ermöglichen, dass Objekte wie Style und DataTemplate wiederverwendbar sind. Weitere Informationen zu Ressourcen finden Sie unter XAML-Ressourcen.
Grundlegendes zu Datenvorlagen
Um zu veranschaulichen, warum DataTemplate wichtig ist, sehen wir uns ein Beispiel für eine Datenbindung an. In diesem Beispiel liegt ein ListBox-Element vor, das an eine Liste von Task
-Objekten gebunden ist. Jedes Task
-Objekt verfügt über TaskName
(string), Description
(string), Priority
(int) und eine Eigenschaft des Typs TaskType
, wobei es sich um Enum
-Element mit dem mit den Werten Home
und Work
handelt.
<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>
Ohne „DataTemplate“
Ohne DataTemplate sieht ListBox derzeit wie folgt aus:
Ohne bestimmte Anweisungen wird durch ListBox standardmäßig ToString
aufgerufen, wenn versucht wird, die Objekte in der Sammlung anzuzeigen. Wenn das Task
-Objekt die ToString
-Methode überschreibt, zeigt ListBox deshalb eine Zeichenfolgendarstellung der einzelnen Quellobjekte in der zugrunde liegenden Sammlung an.
Wenn die Task
-Klasse beispielsweise die ToString
-Methode auf diese Weise außer Kraft setzt, wobei name
das Feld für die TaskName
-Eigenschaft ist:
public override string ToString()
{
return name.ToString();
}
Public Overrides Function ToString() As String
Return _name.ToString()
End Function
ListBox sieht dann folgendermaßen aus:
Das ist jedoch begrenzt und unflexibel. Außerdem können Sie beim Binden an XML-Daten ToString
nicht überschreiben.
Definieren einer einfachen Datenvorlage
Die Lösung besteht darin, eine DataTemplate zu definieren. Eine Möglichkeit dafür besteht darin, die ItemTemplate-Eigenschaft von ListBox auf DataTemplate festzulegen. Was Sie in Ihrem DataTemplate angeben, wird zur visuellen Struktur Ihres Datenobjekts. Im Folgenden finden Sie ein einfaches Beispiel für DataTemplate. Sie geben Anweisungen, dass jedes Element als drei TextBlock-Elemente in StackPanel angezeigt wird. Jedes TextBlock-Element ist an eine Eigenschaft der Task
Klasse gebunden.
<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>
Bei den zugrunde liegenden Daten für die Beispiele in diesem Thema handelt es sich um eine Sammlung von CLR-Objekten. Wenn Sie an XML-Daten binden, sind die grundlegenden Konzepte identisch, aber es gibt einen leichten syntaktischen Unterschied. Anstelle von Path=TaskName
würden Sie z. B. XPath auf @TaskName
festlegen (wenn TaskName
ein Attribut des XML-Knotens ist).
Nun sieht ListBox wie folgt aus:
Erstellen der Datenvorlage als Ressource
Im obigen Beispiel haben Sie DataTemplate inline definiert. Es ist häufiger, sie im Ressourcenabschnitt zu definieren, damit es ein wiederverwendbares Objekt sein kann, wie im folgenden Beispiel:
<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>
Jetzt können Sie myTaskTemplate
als Ressource verwenden, wie im folgenden Beispiel gezeigt:
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplate="{StaticResource myTaskTemplate}"/>
Da myTaskTemplate
eine Ressource ist, können Sie sie nun für andere Steuerelemente verwenden, die über eine Eigenschaft verfügen, die einen DataTemplate-Typ annimmt. Wie oben dargestellt, ist es für ItemsControl-Objekte, wie z. B. ListBox, die ItemTemplate-Eigenschaft. Für ContentControl-Objekte ist es die ContentTemplate-Eigenschaft.
Die DataType-Eigenschaft
Die DataTemplate-Klasse weist eine DataType Eigenschaft auf, die der TargetType-Eigenschaft der Style Klasse sehr ähnlich ist. Anstatt im obigen Beispiel x:Key
für DataTemplate anzugeben, können Sie deshalb wie folgt vorgehen:
<DataTemplate DataType="{x:Type local:Task}">
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate>
Diese DataTemplate wird automatisch auf alle Task
-Objekte angewandt. Beachten Sie, dass x:Key
in diesem Fall implizit festgelegt wird. Wenn Sie also dieser DataTemplate einen x:Key
-Wert zuweisen, überschreiben Sie den impliziten x:Key
, und die DataTemplate wird nicht automatisch angewandt.
Wenn Sie ein ContentControl an eine Auflistung von Task
-Objekten binden, verwendet das ContentControl nicht automatisch die oben genannte DataTemplate. Dies liegt daran, dass die Bindung für ein ContentControl weitere Informationen benötigt, um zwischen der Bindung für eine vollständige Auflistung und der Bindung für einzelne Objekte zu unterscheiden. Wenn das ContentControl die Auswahl eines ItemsControl-Typs nachverfolgt, können Sie die Path-Eigenschaft der ContentControl-Bindung auf „/
“ festlegen, um anzugeben, dass es um das aktuelle Element geht. Ein Beispiel finden Sie unter Binden an eine Sammlung und Anzeigen von Informationen auf Grundlage der Auswahl. Andernfalls müssen Sie die DataTemplate explizit angeben, indem Sie die ContentTemplate-Eigenschaft festlegen.
Die DataType-Eigenschaft ist besonders hilfreich, wenn Sie eine CompositeCollection mit verschiedenen Typen von Datenobjekten haben. Ein Beispiel finden Sie unter Implementieren von CompositeCollection.
Hinzufügen weiterer Elemente zu DataTemplate
Derzeit werden die Daten mit den erforderlichen Informationen angezeigt, aber es gibt definitiv Raum zur Verbesserung. Sie werden nun die Darstellung verbessern, indem Sie ein Border-Element, ein Grid-Element und einige TextBlock-Elemente zur Beschreibung der angezeigten Daten hinzufügen.
<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>
Der folgende Screenshot zeigt ListBox mit diesem geänderten DataTemplate-Element:
Sie können HorizontalContentAlignment für ListBox auf Stretch festlegen, damit die Breite der Elemente die gesamte Fläche einnimmt:
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplate="{StaticResource myTaskTemplate}"
HorizontalContentAlignment="Stretch"/>
Mit der auf Stretch festgelegten HorizontalContentAlignment-Eigenschaft sieht ListBox nun wie folgt aus:
Anwenden von Eigenschaftswerten mit DataTrigger
Aus der aktuellen Darstellung geht nicht hervor, ob es sich bei Task
um eine private oder eine arbeitsbezogene Aufgabe handelt. Denken Sie daran, dass das Task
-Objekt eine TaskType
Eigenschaft vom Typ TaskType
hat, bei der es sich um eine Aufzählung mit Werten Home
und Work
handelt.
Im folgenden Beispiel legt DataTrigger die BorderBrush-Eigenschaft des border
-Elements auf Yellow
fest, wenn die TaskType
-Eigenschaft den Wert TaskType.Home
aufweist.
<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>
Unsere Anwendung sieht nun wie folgt aus. Private Aufgaben werden mit einem gelben Rahmen und Arbeitsaufgaben mit einem hellblauen Rahmen angezeigt:
In diesem Beispiel verwendet DataTrigger ein Setter-Element, um einen Eigenschaftswert festzulegen. Die Triggerklassen verfügen außerdem über die eigenschaften EnterActions und ExitActions, mit denen Sie eine Reihe von Aktionen wie Animationen starten können. Darüber hinaus gibt es auch eine MultiDataTrigger Klasse, mit der Sie Änderungen basierend auf mehreren datengebundenen Eigenschaftswerten anwenden können.
Eine alternative Möglichkeit, denselben Effekt zu erzielen, besteht darin, die BorderBrush Eigenschaft an die TaskType
-Eigenschaft zu binden und einen Wertkonverter zu verwenden, um die Farbe basierend auf dem TaskType
Wert zurückzugeben. Das Erstellen des obigen Effekts mithilfe eines Konverters ist in Bezug auf die Leistung etwas effizienter. Darüber hinaus bietet ihnen das Erstellen eines eigenen Konverters mehr Flexibilität, da Sie Ihre eigene Logik bereitstellen. Welche Technik Sie wählen, hängt letztendlich von Ihrem Szenario und Ihrer Vorliebe ab. Informationen zum Schreiben eines Konverters finden Sie unter IValueConverter.
Was gehört zu einer DataTemplate?
Im vorherigen Beispiel haben Sie den Trigger mit der DataTemplate.Triggers-Eigenschaft in DataTemplate eingefügt. Der Setter des Triggers legt den Wert einer Eigenschaft eines Elements (des Border-Elements) in der DataTemplate fest. Wenn jedoch die Eigenschaften, auf die sich die Setters
beziehen, keine Eigenschaften von Elementen sind, die sich in der aktuellen DataTemplate befinden, ist es möglicherweise sinnvoller, die Eigenschaften mit einem Style für die ListBoxItem-Klasse festzulegen (falls das zu bindende Steuerelement eine ListBox ist). Falls der Trigger z. B. den Opacity-Wert des Elements animieren soll, wenn mit dem Mauszeiger darauf gezeigt wird, definieren Sie Trigger innerhalb eines ListBoxItem-Stils. Ein Beispiel finden Sie unter Einführung in das Beispiel zum Erstellen von Formaten und Vorlagen.
Denken Sie im Allgemeinen daran, dass die DataTemplate auf jede der generierten ListBoxItem angewendet wird (weitere Informationen dazu, wie und wo sie tatsächlich angewendet wird, finden Sie auf der seite ItemTemplate).) DataTemplate bezieht sich nur auf die Darstellung und das Erscheinungsbild der Datenobjekte. In den meisten Fällen gehören alle anderen Aspekte der Präsentation, z. B. wie ein Element aussieht, wenn es ausgewählt wird oder wie die ListBox die Elemente angibt, nicht in die Definition einer DataTemplate. Ein Beispiel finden Sie im Abschnitt Formatieren und Erstellen von Vorlagen für ItemsControl.
Auswählen von DataTemplate anhand von Eigenschaften des Datenobjekts
In Abschnitt "DataType Property" wurde erläutert, dass Sie unterschiedliche Datenvorlagen für unterschiedliche Datenobjekte definieren können. Das ist bei CompositeCollection-Elementen verschiedener Typen oder bei Sammlungen mit Elementen verschiedener Typen besonders hilfreich. Im Abschnitt Anwenden von Eigenschaftswerten mit DataTrigger wurde gezeigt, dass Sie bei einer Sammlung mit Datenobjekten desselben Typs ein DataTemplate-Element erstellen und Änderungen dann mithilfe von Triggern auf Basis der Eigenschaftswerte der einzelnen Datenobjekte anwenden können. Mit Triggern können Sie jedoch Eigenschaftswerte anwenden oder Animationen starten, aber sie bieten Ihnen nicht die Flexibilität, die Struktur Ihrer Datenobjekte zu rekonstruieren. In einigen Szenarien müssen Sie möglicherweise eine andere DataTemplate für Datenobjekte erstellen, die denselben Typ aufweisen, aber unterschiedliche Eigenschaften aufweisen.
Wenn z. B. ein Task
-Objekt einen Priority
-Wert von 1
hat, möchten Sie ihm möglicherweise ein völlig anderes Aussehen verleihen, um als Warnung für Sie selbst zu dienen. In diesem Fall erstellen Sie DataTemplate für die Anzeige der Task
-Objekte mit hoher Priorität. Fügen Sie nun das folgende DataTemplate-Element im Ressourcenabschnitt hinzu:
<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>
In diesem Beispiel wird die DataTemplate.Resources-Eigenschaft verwendet. Die in diesem Abschnitt definierten Ressourcen werden von den Elementen in DataTemplate gemeinsam verwendet.
Um eine Logik bereitzustellen, mit der ausgewählt werden kann, welches DataTemplate-Element auf der Grundlage des Priority
-Werts des Datenobjekts verwendet werden soll, erstellen Sie eine Unterklasse von DataTemplateSelector und überschreiben die SelectTemplate-Methode. Im folgenden Beispiel liefert die SelectTemplate-Methode die Logik, um basierend auf dem Wert der Priority
-Eigenschaft die entsprechende Vorlage zurückzugeben. Die Vorlage, die zurückgegeben werden soll, wird in den Ressourcen des umschließenden Window-Elements gesucht.
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
Anschließend können wir die TaskListDataTemplateSelector
als Ressource deklarieren:
<Window.Resources>
<local:TaskListDataTemplateSelector x:Key="myDataTemplateSelector"/>
</Window.Resources>
Um die Vorlagenauswahlressource verwenden zu können, weisen Sie diese der ItemTemplateSelector-Eigenschaft von ListBox zu. Die ListBox ruft die SelectTemplate-Methode des TaskListDataTemplateSelector
der einzelnen Elemente in der zugrunde liegenden Auflistung auf. Beim Aufruf wird das Datenobjekt als Elementparameter übergeben. Die von der Methode zurückgegebene DataTemplate-Klasse wird dann auf dieses Datenobjekt angewandt.
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
HorizontalContentAlignment="Stretch"/>
Mit der Vorlagenauswahl wird ListBox nun wie folgt angezeigt:
Dies schließt unsere Diskussion über dieses Beispiel ab. Das vollständige Beispiel finden Sie unter Einführung in das Datenvorlagenbeispiel.
Formatierung und Vorlagenerstellung für ItemsControl
Obwohl ItemsControl nicht der einzige Steuerelementtyp ist, mit dem Sie eine DataTemplate verwenden können, ist es üblich, ein ItemsControl an eine Auflistung zu binden. Im Abschnitt Was gehört in ein DataTemplate-Element wurde erläutert, dass sich die Definition von DataTemplate nur auf die Darstellung der Daten beziehen sollte. Um zu wissen, wann es nicht geeignet ist, eine DataTemplate zu verwenden, ist es wichtig, die verschiedenen Stil- und Vorlageneigenschaften zu verstehen, die von der ItemsControlbereitgestellt werden. Im folgenden Beispiel wird die Funktion jeder dieser Eigenschaften veranschaulicht. Das ItemsControl-Element in diesem Beispiel ist an dieselbe Tasks
-Sammlung wie im vorherigen Beispiel gebunden. Zu Demonstrationszwecken werden die Formate und die Vorlagen in diesem Beispiel inline deklariert.
<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>
Im Folgenden sehen Sie einen Screenshot des Beispiels nach dem Rendern:
Beachten Sie, dass Sie anstelle der ItemTemplatedie ItemTemplateSelectorverwenden können. Ein Beispiel finden Sie im vorherigen Abschnitt. Ebenso haben Sie anstelle der ItemContainerStyledie Möglichkeit, die ItemContainerStyleSelectorzu verwenden.
Zwei weitere Stil-bezogene Eigenschaften von ItemsControl, die hier nicht angezeigt werden, sind GroupStyle und GroupStyleSelector.
Unterstützung für hierarchische Daten
Bisher wurde nur erläutert, wie eine einzelne Sammlung gebunden und angezeigt wird. Manchmal verfügen Sie über eine Sammlung, die andere Sammlungen enthält. Die HierarchicalDataTemplate-Klasse soll mit HeaderedItemsControl-Typen verwendet werden, um solche Daten anzuzeigen. Im folgenden Beispiel ist ListLeagueList
eine Liste League
Objekte. Jedes League
-Objekt verfügt über ein Name
und eine Sammlung von Division
-Objekten. Jedes Division
-Element verfügt über Name
und eine Sammlung von Team
-Objekten, und jedes Team
-Objekt verfügt über 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>
Das Beispiel zeigt, dass Sie mit der Verwendung von HierarchicalDataTemplatelistendaten, die andere Listen enthalten, ganz einfach anzeigen können. Im Folgenden sehen Sie einen Screenshot des Beispiels.
Screenshot
Weitere Informationen
.NET Desktop feedback