TOC

This article has been localized into Russian by the community.

Элемент DataGrid:

DataGrid и детали строк

Часто необходимо, чтобы при использовании элемента DataGrid была возможность показать детали каждой строки (чаще всего под самой строкой). В WPF DataGrid поддерживает данную функциональность, и, к счастью, она довольно проста в использовании. Давайте начнем, а позже обсудим, как это работает, и что дает разработчику:

<Window x:Class="WpfTutorialSamples.DataGrid_control.DataGridDetailsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataGridDetailsSample" Height="200" Width="400">
	<Grid Margin="10">
		<DataGrid Name="dgUsers" AutoGenerateColumns="False">
			<DataGrid.Columns>
				<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
				<DataGridTextColumn Header="Birthday" Binding="{Binding Birthday}" />
			</DataGrid.Columns>
			<DataGrid.RowDetailsTemplate>
				<DataTemplate>
					<TextBlock Text="{Binding Details}" Margin="10" />
				</DataTemplate>
			</DataGrid.RowDetailsTemplate>
		</DataGrid>
	</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;

namespace WpfTutorialSamples.DataGrid_control
{
	public partial class DataGridDetailsSample : Window
	{
		public DataGridDetailsSample()
		{
			InitializeComponent();
			List<User> users = new List<User>();
			users.Add(new User() { Id = 1, Name = "John Doe", Birthday = new DateTime(1971, 7, 23) });
			users.Add(new User() { Id = 2, Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17) });
			users.Add(new User() { Id = 3, Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2) });

			dgUsers.ItemsSource = users;
		}
	}

	public class User
	{
		public int Id { get; set; }

		public string Name { get; set; }

		public DateTime Birthday { get; set; }

		public string Details
		{
			get
			{
				return String.Format("{0} was born on {1} and this is a long description of the person.", this.Name, this.Birthday.ToLongDateString());
			}
		}
	}
}

Как Вы можете заметить, я расширил пример из предыдущей главы, добавив в класс User новое свойство - Description (описание). Оно возвращает некоторую информацию о пользователе (User) для нашей строки с деталями.

В разметке к примеру я определил несколько столбцов и использовал RowDetailsTemplate для создания шаблона строки с деталями. Как Вы можете заметить, этот механизм работает похоже на другие шаблоны, существующие в WPF: я использовал DataTemplate с элементом управления внутри (может быть несколько элементов), со стандартным связыванием данных для получения информации из Description (c помощью свойства класса User).

Запустите пример либо изучите скриншот этого примера и Вы увидите, что дополнительная информация будет теперь показана под выбранной строкой. Если выбрать другую строку, то под ней появится строка с деталями, а предыдущая строка с деталями будет скрыта.

Управление отображением строки деталей

Используя свойство RowDetailsVisibilityMode, Вы можете изменять поведение вышеупомянутого механизма. По умолчанию оно определено как VisibleWhenSelected, в этом случае строка деталей будет видна исключительно при выбранной строке-родителе. Вы можете изменить это свойство на Visible или Collapsed. Если выбрать Visible, то все строки с деталями будут видны всегда, как здесь:

А если выбрать Collapsed, то детали будут все время скрыты.

Больше деталей

Первый пример текущей главы определенно был скучным, ведь мы использовали только элемент TextBlock. Конечно же, используя DataTemplate, Вы можете сделать все что захотите, так что я решил слегка расширить предыдущий пример, чтобы дать Вам понять, какие открываются возможности с использованием шаблонов. Теперь наш пример выглядит таким образом:

Как Вы можете заметить из кода примера, изменения больше всего здесь касаются расширения шаблона деталей с помощью контейнера, который позволяет содержать в строке деталей другие контейнеры либо элементы управления. Используя контейнер Grid, мы можем придать данным вид таблицы, а элемент Image позволяет отображать изображение "пользователя" (которое желательно загружать из локального хранилища, а не удаленного. Так же, извините за мою лень, за то, что я не нашел подходящих фотографий Jane и Sammy).

<Window x:Class="WpfTutorialSamples.DataGrid_control.DataGridDetailsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataGridDetailsSample" Height="300" Width="300">
	<Grid Margin="10">
		<DataGrid Name="dgUsers" AutoGenerateColumns="False">
			<DataGrid.Columns>
				<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
				<DataGridTextColumn Header="Birthday" Binding="{Binding Birthday}" />
			</DataGrid.Columns>
			<DataGrid.RowDetailsTemplate>
				<DataTemplate>
					<DockPanel Background="GhostWhite">
						<Image DockPanel.Dock="Left" Source="{Binding ImageUrl}" Height="64" Margin="10" />
						<Grid Margin="0,10">
							<Grid.ColumnDefinitions>
								<ColumnDefinition Width="Auto" />
								<ColumnDefinition Width="*" />
							</Grid.ColumnDefinitions>
							<Grid.RowDefinitions>
								<RowDefinition Height="Auto" />
								<RowDefinition Height="Auto" />
								<RowDefinition Height="Auto" />
							</Grid.RowDefinitions>

							<TextBlock Text="ID: " FontWeight="Bold" />
							<TextBlock Text="{Binding Id}" Grid.Column="1" />
							<TextBlock Text="Name: " FontWeight="Bold" Grid.Row="1" />
							<TextBlock Text="{Binding Name}" Grid.Column="1" Grid.Row="1" />
							<TextBlock Text="Birthday: " FontWeight="Bold" Grid.Row="2" />
							<TextBlock Text="{Binding Birthday, StringFormat=d}" Grid.Column="1" Grid.Row="2" />

						</Grid>
					</DockPanel>
				</DataTemplate>
			</DataGrid.RowDetailsTemplate>
		</DataGrid>
	</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;

namespace WpfTutorialSamples.DataGrid_control
{
	public partial class DataGridDetailsSample : Window
	{
		public DataGridDetailsSample()
		{
			InitializeComponent();
			List<User> users = new List<User>();
			users.Add(new User() { Id = 1, Name = "John Doe", Birthday = new DateTime(1971, 7, 23), ImageUrl = "http://www.wpf-tutorial.com/images/misc/john_doe.jpg" });
			users.Add(new User() { Id = 2, Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17) });
			users.Add(new User() { Id = 3, Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2) });

			dgUsers.ItemsSource = users;
		}
	}

	public class User
	{
		public int Id { get; set; }

		public string Name { get; set; }

		public DateTime Birthday { get; set; }

		public string ImageUrl { get; set; }
	}
}

В итоге

Возможность представлять детали в строке DataGrid является крайне полезной, а в WPF использование этого механизма является простым, а так же DataGrid позволяет кастомизировать данные, что Вы наверняка заметили в примерах выше.


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!