TOC

This article has been localized into Vietnamese by the community.

TreeView control:

TreeView, data binding and multiple templates

Giống như tất cả các Control trong WPF khác, TreeView cũng hỗ trợ gắn kết dữ liệu, nhưng với bản chất có thứ bậc, một DataTemplate (Khuôn mẫu Dữ liệu) thường không đủ. Thay vào đó chúng ta sử dụng HierarchicalDataTemplate (Khuôn mẫu Dữ liệu Có thứ bậc) cho phép ta vừa tạo khuôn mẫu cho một nút vừa kiểm soát xem thuộc tính nào được sử dụng như nguồn dữ liệu cho các mục con của nút đó

TreeView ràng buộc dữ liệu cơ bản

Trong ví dụ sau, tôi sẽ chỉ cho bạn thấy việc bắt đầu dễ dàng như thế nào với 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; }
	}

}

Trong XAML, tôi đã chỉ định HierarchicalDataTemplate cho ItemTemplate của TreeView. Tôi hướng dẫn nó sử dụng thuộc tính Items để tìm các mục con, bằng cách đặt thuộc tính ItemsSource của mẫu và bên trong nó tôi xác định mẫu thực tế, hiện tại chỉ bao gồm một TextBlock được liên kết với thuộc tính Title.

Ví dụ đầu tiên này rất đơn giản, trên thực tế đơn giản đến mức chúng ta có thể vừa thêm các mục TreeView theo cách thủ công, thay vì tạo một tập hợp các đối tượng và sau đó liên kết với chúng. Tuy nhiên, ngay khi mọi thứ trở nên phức tạp hơn một chút, những lợi thế của việc sử dụng các ràng buộc dữ liệu trở nên rõ ràng hơn.

Nhiều templates cho các loại khác nhau

Trong ví dụ tiếp theo, tôi đã lấy một trường hợp phức tạp hơn một chút, nơi tôi muốn cho thấy một cây của các gia đình và các thành viên của nó. Một gia đình nên được đại diện theo một cách, trong khi mỗi thành viên của nó nên được thể hiện theo một cách khác. Tôi đạt được điều này bằng cách tạo hai mẫu khác nhau và chỉ định chúng là tài nguyên của tree (hoặc Window hoặc Application - điều đó thực sự tùy thuộc vào bạn), và sau đó cho phép TreeView chọn mẫu chính xác dựa trên loại dữ liệu cơ bản.

Đây là code - phần giải thích về nó sẽ có ngay sau đó:

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

Như đã đề cập, hai templates được khai báo là một phần của tài nguyên TreeView, cho phép TreeView chọn mẫu thích hợp dựa trên loại dữ liệu mà nó sắp hiển thị. Mẫu được xác định cho loại Family là mẫu phân cấp, sử dụng thuộc tính Members để hiển thị các family members.

Template được xác định cho FamilyMember là một DataTemplate thông thường, vì loại này không có bất kỳ thành viên con nào. Tuy nhiên, nếu chúng tôi muốn mỗi FamilyMember giữ một bộ sưu tập con cái của họ và có lẽ là con của họ, thì chúng tôi sẽ sử dụng một mẫu phân cấp thay thế.

Trong cả hai mẫu, chúng tôi sử dụng một hình ảnh đại diện cho một gia đình hoặc một thành viên gia đình và sau đó chúng tôi cũng hiển thị một số dữ liệu thú vị về nó, như số lượng thành viên gia đình hoặc tuổi của người đó.

Trong code-behind, chúng tôi chỉ cần tạo hai cá thể Gia đình, điền vào mỗi nhóm với một nhóm thành viên và sau đó thêm từng gia đình vào danh sách, sau đó được sử dụng làm nguồn vật phẩm cho TreeView.

Tổng kết

Sử dụng liên kết dữ liệu(data binding), TreeView rất tùy biến và với khả năng chỉ định nhiều mẫu để hiển thị các loại dữ liệu khác nhau, khả năng là gần như vô tận.


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!