Table of Contents

Как создать контрол TreeList и привязать его к иерархическому источнику данных

В этом примере создаются следующие контролы:

  • Контрол TreeListControl, который отображает иерархический список объектов Employee. Включен выбор нескольких узлов, что позволяет вам выбирать (выделять) несколько узлов одновременно.
  • Текстовый редактор, отображающий имя сотрудника, который в данный момент находится в TreeList.
  • Контрол со списком, в котором отображаются имена сотрудников, выбранных (выделенных) в TreeList.

TreeList привязан к бизнес-объекту Employee, который представляет собой Иерархический источник данных . Он содержит коллекцию Subordinates, содержимое которой должно отображаться в виде дочерних узлов.

В приведенном примере для настройки TreeListControl используются следующие основные свойства:

  • DataControlBase.ItemsSource — Указывает источник данных контрола.
  • TreeListControl.Columns — Определяет коллекцию столбцов TreeList, привязанных к свойствам источника данных.
  • TreeListControlBase.ChildrenFieldName — Указывает имя поля (свойства), в котором хранятся дочерние данные в нижележащем бизнес-объекте.
  • TreeListControlBase.HasChildrenFieldName — указывает имя поля (свойства), которое возвращает true, если бизнес-объект имеет дочерние данные, и false, в противном случае.
  • TreeListControlBase.SelectionMode — Позволяет выбирать несколько узлов.

В режиме выбора нескольких узлов пользователь может выбрать (выделить) несколько узлов с помощью мыши и клавиатуры. Например, пользователь может удерживать нажатой клавишу CTRL и щелкать по отдельным узлам, чтобы выбрать их. TreeList позволяет вам получить доступ к выбранным в данный момент узлам из коллекции DataControlBase.SelectedItems.

Следующие два контрола используются для отображения информации о сфокусированных в данный момент и выбранных узлах TreeList:

  • Текстовый редактор отображает имя объекта Employee сфокусированного узла. Контрол привязан к свойству FocusedItem TreeList.
  • В окне списка отображаются имена объектов Employee, которые соответствуют выбранным узлам TreeList.

Пример находит два узла TreeList по именам и выбирает их при запуске приложения.

<Window xmlns="https://github.com/avaloniaui"
        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:vm="using:TreeControls"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        xmlns:mxtl="clr-namespace:Eremex.AvaloniaUI.Controls.TreeList;assembly=Eremex.Avalonia.Controls"
        xmlns:mxe="clr-namespace:Eremex.AvaloniaUI.Controls.Editors;assembly=Eremex.Avalonia.Controls"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        x:Class="TreeControls.MainWindow"
        Title="TreeControls">
    <Grid ColumnDefinitions="*, 200">
        <mxtl:TreeListControl
            Grid.Column="0"
            Name="treeList1"
            ItemsSource="{Binding Employees}"
            ChildrenFieldName="Subordinates"
            HasChildrenFieldName="HasChildren"
            SelectionMode="Multiple"
            SelectedItems="{Binding SelectedEmployees}"
            >
            <mxtl:TreeListControl.Columns>
                <mxtl:TreeListColumn Name="colName" FieldName="Name" Header="Name" />
                <mxtl:TreeListColumn Name="colBirthdate" FieldName="Birthdate" Header="Birthdate"/>
            </mxtl:TreeListControl.Columns>
        </mxtl:TreeListControl>

        <StackPanel Orientation="Vertical" Grid.Column="1" >
            <Label Content="Focused Item:"></Label>
            
            <mxe:TextEditor 
                ReadOnly="True"
                EditorValue="{Binding #treeList1.FocusedItem.Name}"
            >
            </mxe:TextEditor>
            <Label Content="Selected Items:" Margin="0,20,0,0"></Label>
            <ListBox Name="listBox"
                     Margin="6"
                     ItemsSource="{Binding SelectedEmployees}"
                 >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </Grid>
</Window>
using Avalonia.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using Eremex.AvaloniaUI.Controls.TreeList;
using System;
using System.Collections.ObjectModel;

namespace TreeControls
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            MyViewModel viewModel = new MyViewModel();
            this.DataContext = viewModel;

            InitializeComponent();

            treeList1.SelectionMode = Eremex.AvaloniaUI.Controls.DataControl.RowSelectionMode.Multiple;
            treeList1.ExpandAllNodes();
            TreeListNode node1 = treeList1.FindNode(node => (node.Content as Employee).Name.Contains("Sam"));
            TreeListNode node2 = treeList1.FindNode(node => (node.Content as Employee).Name.Contains("Dan"));
            treeList1.BeginSelection();
            treeList1.ClearSelection();
            treeList1.SelectNode(node1);
            treeList1.SelectNode(node2);
            treeList1.EndSelection();
        }
    }

    public partial class MyViewModel : ObservableObject
    {
        public MyViewModel()
        {
            Employee p1 = new Employee() { Name = "Mark Douglas", Birthdate = new DateTime(1990, 01, 5) };
            Employee p2 = new Employee() { Name = "Mary Watson", Birthdate = new DateTime(1985, 12, 17) };
            Employee p3 = new Employee() { Name = "Alex Wude", Birthdate = new DateTime(2000, 10, 7) };
            Employee p4 = new Employee() { Name = "Sam Louis", Birthdate = new DateTime(1975, 8, 27) };
            Employee p5 = new Employee() { Name = "Dan Miller", Birthdate = new DateTime(1981, 3, 6) };
            p1.Subordinates.Add(p2);
            p1.Subordinates.Add(p3);
            p2.Subordinates.Add(p4);
            p3.Subordinates.Add(p5);

            Employees = new ObservableCollection<Employee>() { p1 };

            SelectedEmployees = new();
        }

        public ObservableCollection<Employee> Employees { get; set; }

        public ObservableCollection<Employee>? SelectedEmployees { get; set; }
    }

    public partial class Employee : ObservableObject
    {
        [ObservableProperty]
        public string name = "";

        [ObservableProperty]
        public DateTime? birthdate = null;

        public ObservableCollection<Employee> Subordinates { get; } = new();

        public bool HasChildren { get { return Subordinates.Count > 0; } }
    }
}


* Эта страница была создана автоматически с помощью сервиса машинного перевода Яндекс Переводчик.