TOC

This article is currently in the process of being translated into Slovak (~85% done).

The TreeView control:

TreeView, data binding and multiple templates

WPF TreeView podporuje data binding,, podobne ako všetky ostatné ovládacie prvky WPF, ale pretože TreeView je svojou povahou hierarchický, normálny DataTemplate často nebude stačiť. Namiesto toho používame HierarchicalDataTemplate, ktorý nám umožňuje šablónovať samotný stromový uzol a zároveň riadiť, ktorá vlastnosť sa má použiť ako zdroj pre podradené položky uzla.

A basic data bound TreeView

V nasledujúcom príklade vám ukážem, aké ľahké je začať s HierarchicalDataTemplate:

<Window x:Class="WpfTutorialSamples.TreeView_control.TreeViewDataBindingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:self="clr-namespace:WpfTutorialSamples.TreeView_control"
        Title="TreeViewDataBindingSample" Height="150" Width="200">
    <Grid Margin="10">
		<TreeView Name="trvMenu">
			<TreeView.ItemTemplate>
				<HierarchicalDataTemplate DataType="{x:Type self:MenuItem}" ItemsSource="{Binding Items}">
					<TextBlock Text="{Binding Title}" />
				</HierarchicalDataTemplate>
			</TreeView.ItemTemplate>
		</TreeView>
	</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.IO;
using System.Collections.ObjectModel;

namespace WpfTutorialSamples.TreeView_control
{
	public partial class TreeViewDataBindingSample : Window
	{
		public TreeViewDataBindingSample()
		{
			InitializeComponent();
			MenuItem root = new MenuItem() { Title = "Menu" };
			MenuItem childItem1 = new MenuItem() { Title = "Child item #1" };
			childItem1.Items.Add(new MenuItem() { Title = "Child item #1.1" });
			childItem1.Items.Add(new MenuItem() { Title = "Child item #1.2" });
			root.Items.Add(childItem1);
			root.Items.Add(new MenuItem() { Title = "Child item #2" });
			trvMenu.Items.Add(root);
		}
	}

	public class MenuItem
	{
		public MenuItem()
		{
			this.Items = new ObservableCollection<MenuItem>();
		}

		public string Title { get; set; }

		public ObservableCollection<MenuItem> Items { get; set; }
	}

}

V značke XAML som určil HierarchicalDataTemplate pre ItemTemplate v TreeView. Inštruujem ho, aby použil vlastnosť Items na nájdenie podradených položiek nastavením vlastnosti ItemsSource šablóny a vo vnútri definujem aktuálnu šablónu, ktorá zatiaľ len pozostáva z bloku TextBlock viazaného na vlastnosť Title .

Tento prvý príklad bol veľmi jednoduchý, v skutočnosti taký jednoduchý, že sme mohli tiež jednoducho pridať položky TreeView ručne, namiesto generovania sady objektov a následného naviazania na ne. Akonáhle sa však situácia trochu skomplikuje, výhody použitia dátových väzieb sa stanú zrejmejšími.

Multiple templates for different types

V nasledujúcom príklade som vzal o niečo zložitejší prípad, keď chcem ukázať strom rodín a ich členov. Rodina by mala byť zastúpená jedným spôsobom, zatiaľ čo každý z jej členov by mal byť uvedený iným spôsobom. Dosiahnem to vytvorením dvoch rôznych šablón a ich špecifikovaním ako zdrojov stromu (alebo okna alebo aplikácie - to je skutočne na vás) a potom umožníme TreeView vybrať správnu šablónu na základe podkladového typu údajov.

Tu je kód - jeho vysvetlenie bude nasledovať hneď na to:

<Window x:Class="WpfTutorialSamples.TreeView_control.TreeViewMultipleTemplatesSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:self="clr-namespace:WpfTutorialSamples.TreeView_control"
        Title="TreeViewMultipleTemplatesSample" Height="200" Width="250">
	<Grid Margin="10">
		<TreeView Name="trvFamilies">
			<TreeView.Resources>
				<HierarchicalDataTemplate DataType="{x:Type self:Family}" ItemsSource="{Binding Members}">
					<StackPanel Orientation="Horizontal">
						<Image Source="/WpfTutorialSamples;component/Images/group.png" Margin="0,0,5,0" />
						<TextBlock Text="{Binding Name}" />
						<TextBlock Text=" [" Foreground="Blue" />
						<TextBlock Text="{Binding Members.Count}" Foreground="Blue" />
						<TextBlock Text="]" Foreground="Blue" />
					</StackPanel>
				</HierarchicalDataTemplate>
				<DataTemplate DataType="{x:Type self:FamilyMember}">
					<StackPanel Orientation="Horizontal">
						<Image Source="/WpfTutorialSamples;component/Images/user.png" Margin="0,0,5,0" />
						<TextBlock Text="{Binding Name}" />
						<TextBlock Text=" (" Foreground="Green" />
						<TextBlock Text="{Binding Age}" Foreground="Green" />
						<TextBlock Text=" years)" Foreground="Green" />
					</StackPanel>
				</DataTemplate>
			</TreeView.Resources>
		</TreeView>
	</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Collections.ObjectModel;

namespace WpfTutorialSamples.TreeView_control
{
	public partial class TreeViewMultipleTemplatesSample : Window
	{
		public TreeViewMultipleTemplatesSample()
		{
			InitializeComponent();

			List<Family> families = new List<Family>();

			Family family1 = new Family() { Name = "The Doe's" };
			family1.Members.Add(new FamilyMember() { Name = "John Doe", Age = 42 });
			family1.Members.Add(new FamilyMember() { Name = "Jane Doe", Age = 39 });
			family1.Members.Add(new FamilyMember() { Name = "Sammy Doe", Age = 13 });
			families.Add(family1);

			Family family2 = new Family() { Name = "The Moe's" };
			family2.Members.Add(new FamilyMember() { Name = "Mark Moe", Age = 31 });
			family2.Members.Add(new FamilyMember() { Name = "Norma Moe", Age = 28 });
			families.Add(family2);

			trvFamilies.ItemsSource = families;
		}
	}

	public class Family
	{
		public Family()
		{
			this.Members = new ObservableCollection<FamilyMember>();
		}

		public string Name { get; set; }

		public ObservableCollection<FamilyMember> Members { get; set; }
	}

	public class FamilyMember
	{
		public string Name { get; set; }

		public int Age { get; set; }
	}
}

Ako už bolo spomenuté, tieto dve šablóny sa deklarujú ako súčasť zdrojov TreeView, čo umožňuje TreeView vybrať príslušnú šablónu na základe typu údajov, ktorý sa má zobraziť. Šablóna definovaná pre typ Family je hierarchická šablóna a pomocou vlastnosti Members zobrazuje svojich rodinných príslušníkov.

Šablóna definovaná pre typ FamilyMember je bežná DataTemplate, pretože tento typ nemá žiadnych podradených členov. Keby sme však chceli, aby si každý člen rodiny rodiny ponechal zbierku svojich detí a možno ich detí, potom by sme namiesto toho použili hierarchickú šablónu.

V obidvoch šablónach používame obrázok predstavujúci rodinu alebo člena rodiny a potom o nej tiež ukážeme niektoré zaujímavé údaje, ako napríklad počet členov rodiny alebo vek osoby.

V zadanom kóde jednoducho vytvoríme dve inštancie Family, každú z nich naplníme množinou členov a potom pridáme každú z rodín do zoznamu, ktorý sa potom použije ako zdroj položiek pre TreeView.

Summary

Using data binding, the TreeView is very customizable and with the ability to specify multiple templates for rendering different data types, the possibilities are almost endless.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!