WPF 에 밖에 없는 편리 기능, 계층을 가지는 데이터를 표시한다 HierarchicalDataTemplate

10719 단어 C#WPF
오랜만의 WPF 재료입니다. WPF로 시작한 MS 기반 XAML에서 화면을 정의하는 기술 중에서 후발 플랫폼에서는 채택되지 않은 몇 가지 기능이 있습니다.

MultiBinding이라든지 이번에 소개하는 HierarchicalDataTemplate가 그에 해당합니다. 이번에는 HierarchicalDataTemplate에 주목하겠습니다.

전제



WPF는 DataTemplate이라는 데이터를 사용하여 데이터를 화면에 표시할 때 어떻게 표시할지에 대한 정의를 작성합니다. 예를 들어 다음과 같은 Person 클래스가 있다고 가정합니다.
namespace Xxx
{
  public class Person
  {
    public string Name { get; set; }
  }
}

이것을 화면에 문자열로서 Name 을 표시하고 싶다면 다음과 같은 느낌의 템플릿이 됩니다.
<!-- 何処かで xmlns:xxx="clr-namespace:Xxx" を定義している前提 -->
<DataTemplate TargetType="xxx:Person">
  <TextBlock Text="{Binding Name}" />
</DataTemplate>

DataTemplate 대응 컨트롤에는 ContentTemplate 나 ItemTemplate 라고 하는 프로퍼티이 있어, 여기에 상기의 DataTemplate 의 정의를 설정하는 것으로 외형을 지정할 수 있습니다.

HierarchicalDataTemplate



HierarchicalDataTemplate은 계층 구조를 가진 데이터의 모양을 정의하는 템플릿입니다. 예를 들어 다음과 같은 Person 클래스가 있다고 가정합니다.
using System.Collections.ObjectModel;

namespace WpfApp40
{
    public class Person
    {
        public string Name { get; set; }
        public ObservableCollection<Person> Children { get; } = new ObservableCollection<Person>();
    }
}

앞의 예와 비교하면 Children 속성이 증가하고 있습니다! ! Name 을 표시한 후에 아이 요소로서 Children 의 Name 도 열거하고 싶다고 하는 경우를 생각해 봅시다. 계층 구조의 데이터의 표시에 대응한 컨트롤로서는 TreeView 나 ContextMenu 컨트롤이 있습니다. 이번에는 여러 사정에 따라 ContextMenu에서 해보려고 합니다.

MainPage.xaml.cs 의 DataContext 에 방금 전의 클래스의 배열을 넣어 둡니다.
using System.Windows;

namespace WpfApp40
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new[]
            {
                new Person
                {
                    Name = "Taro1",
                    Children =
                    {
                        new Person 
                        { 
                            Name = "Taro1-1",
                            Children =
                            {
                                new Person { Name = "Taro1-1-1" },
                                new Person { Name = "Taro1-1-2" },
                                new Person { Name = "Taro1-1-3" },
                                new Person { Name = "Taro1-1-4" },
                            }
                        },
                        new Person { Name = "Taro1-2" },
                        new Person { Name = "Taro1-3" },
                    },
                },
                new Person
                {
                    Name = "Taro2",
                    Children =
                    {
                        new Person { Name = "Taro2-1" },
                        new Person { Name = "Taro2-2" },
                        new Person { Name = "Taro2-3" },
                    },
                },
            };
        }
    }
}

그런 다음 화면에 버튼을 놓고 해당 버튼의 컨텍스트 메뉴에 HierarchicalDataTemplate을 지정합니다. 포인트는 DataTemplate 때와 같이 Name property를 TextBlock 로 표시하고 있는 것에 더해 ItemsSource property로 아이 요소로서 Children property를 지정하고 있는 곳입니다. 이렇게 하면, 아이 요소에는 Children 안의 Person 클래스가 열거되어, 그 외형이 다시 HierarchicalDataTemplate 로 표시되는 형태가 됩니다.
<Window x:Class="WpfApp40.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp40"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Content="XXXX" MinWidth="250">
            <Button.ContextMenu>
                <ContextMenu ItemsSource="{Binding}">
                    <ContextMenu.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                            <TextBlock Text="{Binding Name}" />
                        </HierarchicalDataTemplate>
                    </ContextMenu.ItemTemplate>
                </ContextMenu>
            </Button.ContextMenu>
        </Button>
    </Grid>
</Window>

실행하면 다음과 같습니다.



이것에 DataTemplateSelector 라든지를 조합하면, 비교적 자유자재로 계층 구조를 가진 데이터를 표현할 수 있어 낭비합니다.

요약



WPF 강한.

좋은 웹페이지 즐겨찾기