Skip to content

Группы

Вы можете использовать полосы для визуального объединения столбцов вместе. Контрол DataGrid отображает полосы в качестве дополнительных заголовков над заголовками столбцов. Заголовки как группы, так и столбца могут содержать текст, картинки или пользовательский контент. Вы также можете создавать иерархические группы с неограниченным количеством уровней вложенности.

На следующей картинке показан контрол DataGrid с четырьмя диапазонами: "Клиент", "Сведения", "Адрес" и "Контакт".:

datagrid-bands

Следующие подходы позволяют создавать группы столбцов:

Создание групп вручную

Выполните следующие действия, чтобы вручную создать группы:

  1. Создайте объекты band (экземпляры класса GridBand) и добавьте их в коллекцию DataGridControl.Bands.

    Назначьте уникальные имена диапазонов созданным диапазонам, используя свойство GridBand.BandName.

    <mxdg:DataGridControl.Bands>
        <mxdg:GridBand BandName="Customer" HeaderHorizontalAlignment="Center"/>
        <mxdg:GridBand BandName="Details" HeaderHorizontalAlignment="Center"/>
    </mxdg:DataGridControl.Bands>
    

    Вы можете создать иерархическую структуру бэндов. Для создания вложенных бэндов:

    • В коде: добавьте полосы в коллекцию GridBand.Bands.
    • В XAML: Определите вложенные диапазоны непосредственно между открывающим и закрывающим тегами GridBand.
    <mxdg:GridBand BandName="Details" HeaderHorizontalAlignment="Center">
        <mxdg:GridBand BandName="DetailsAddress" Header="Address" HeaderHorizontalAlignment="Center"/>
        <mxdg:GridBand BandName="DetailsContact" Header="Contact" HeaderHorizontalAlignment="Center"/>
    </mxdg:GridBand>
    

    Свойство GridBand.Header позволяет задать пользовательское содержимое (например, пользовательский текст) для бэнда. Если это свойство не задано, в заголовке бэнда отображается значение свойства GridBand.BandName.

  2. Привязать столбцы к определенным диапазонам, установив для свойства GridColumn.BandName каждого столбца значение соответствующего имени диапазона (GridBand.BandName).

    <mxdg:DataGridControl.Columns>
        <mxdg:GridColumn FieldName="FirstName" BandName="Customer" Width="*"/>
        <mxdg:GridColumn FieldName="City" BandName="DetailsAddress" Width="*"/>
        <mxdg:GridColumn FieldName="Phone" BandName="DetailsContact" Width="*"/>
        <!-- ... -->
    </mxdg:DataGridControl.Columns>
    

Столбцы расположены в контролах размещения DataGrid в соответствии с их свойствами GridColumn.VisibleIndex. Контрол не перестраивает столбцы автоматически, чтобы сгруппировать их по диапазонам.

datagrid-bands-not-keep-columns-together

Смотрите Порядок расположения столбцов и полос

Связанный API

  • Класс GridBand — инкапсулирует диапазон столбцов.
  • GridBand.BandName — Уникальное имя, используемое для идентификации диапазона и привязывающее его к столбцам.
  • GridColumn.BandName — название группы, связанной с столбцом. Это значение соответствует значению свойства GridBand.BandName.
  • DataGridControl.Bands — Коллекция корневых бэндов.
  • GridBand.Bands — Коллекция детских браслетов для этой группы.

Пример - Вручную создайте группы столбцов в DataGrid контроле

В следующем примере создаются группы и присваиваются им столбцы, как показано на картинке ниже:

datagrid-bands-example

  • Группы "Клиент", "Адрес" и "Контакт" связаны со столбцами таблицы.
  • Группе "Подробности" принадлежат две вложенные группы ("Адрес" и "Контакт"). Этот диапазон напрямую не связан с столбцами.

Каждому диапазону присваивается уникальное имя с использованием свойства GridBand.BandName. Чтобы связать столбцы с определенным диапазоном, установите для свойства GridColumn.BandName столбца значение BandName целевого диапазона.

Свойство DataGridControl.Bands определяет структуру бэндов. Чтобы создать вложенные бэнды, определите их как дочерние по отношению к родительскому бэнду.

<!-- MainWindow.axaml file -->
<mx:MxWindow xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:DataGridColumnBands.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mx="https://schemas.eremexcontrols.net/avalonia"
        xmlns:mxdg="https://schemas.eremexcontrols.net/avalonia/datagrid"
        xmlns:svg="using:Avalonia.Svg.Skia"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="DataGridColumnBands.Views.MainWindow"
        x:DataType="vm:MainWindowViewModel"
        Icon="/Assets/EMXControls.ico"
        Title="DataGridColumnBands">

    <Design.DataContext>
        <vm:MainWindowViewModel/>
    </Design.DataContext>

    <Grid RowDefinitions="Auto *" Margin="10">
        <mxdg:DataGridControl BorderBrush="LightGray" BorderThickness="1" Name="gridControl1"
                              ItemsSource="{Binding Employees}"
                              AllowColumnMoving="False"
                          >
            <mxdg:DataGridControl.Bands>
                <mxdg:GridBand BandName="Customer" HeaderHorizontalAlignment="Center">
                    <mxdg:GridBand.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <svg:Svg Path="/Assets/customer.svg" Width="16" Height="16" Margin="5" />
                                <TextBlock Text="{Binding}" VerticalAlignment="Center"/>
                            </StackPanel>
                        </DataTemplate>
                    </mxdg:GridBand.HeaderTemplate>

                </mxdg:GridBand>
                <mxdg:GridBand BandName="Details" HeaderHorizontalAlignment="Center">
                    <mxdg:GridBand BandName="DetailsAddress" Header="Address" HeaderHorizontalAlignment="Center"/>
                    <mxdg:GridBand BandName="DetailsContact" Header="Contact" HeaderHorizontalAlignment="Center"/>
                </mxdg:GridBand>
            </mxdg:DataGridControl.Bands>

            <mxdg:DataGridControl.Columns>
                <mxdg:GridColumn Width="*" FieldName="FirstName" BandName="Customer"/>
                <mxdg:GridColumn Width="*" FieldName="LastName" BandName="Customer"/>
                <mxdg:GridColumn Width="*" FieldName="Title" BandName="Customer"/>
                <mxdg:GridColumn Width="*" FieldName="BirthDate" BandName="Customer"/>
                <mxdg:GridColumn Width="*" FieldName="Address" BandName="DetailsAddress"/>
                <mxdg:GridColumn Width="*" FieldName="City" BandName="DetailsAddress"/>
                <mxdg:GridColumn Width="*" FieldName="Country" BandName="DetailsAddress"/>
                <mxdg:GridColumn Width="*" FieldName="EMail" BandName="DetailsContact" Header="E-mail"/>
                <mxdg:GridColumn Width="*" FieldName="Phone" BandName="DetailsContact"/>
            </mxdg:DataGridControl.Columns>
        </mxdg:DataGridControl>
    </Grid>
</mx:MxWindow>
//MainWindow.axaml.cs file
using Avalonia.Controls;
using Eremex.AvaloniaUI.Controls.Common;
using DataGridColumnBands.ViewModels;

namespace DataGridColumnBands.Views
{
    public partial class MainWindow : MxWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
    }
}
//MainWindowViewModel.cs file
using System.ComponentModel;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.Generic;
using System;

namespace DataGridColumnBands.ViewModels
{
    public partial class MainWindowViewModel : ViewModelBase
    {
        [ObservableProperty]
        IList<CustomerInfo> employees;

        public MainWindowViewModel()
        {
            Employees = GetSampleCustomers();
        }

        public static List<CustomerInfo> GetSampleCustomers() => new()
        {
            new("Raj", "Patel", "Financial Analyst", new DateTime(1988, 7, 12),
                "15 Gandhi Road", "Mumbai", "India", "raj.patel@example.in", "+91 22 6789 1234"),
            new("Yuki", "Tanaka", "Owner", new DateTime(1985, 3, 25),
                "3-5-1 Roppongi", "Tokyo", "Japan", "y.tanaka@example.jp", "+81 3 9876 5432"),
            new("Wei", "Zhang", "Financial Analyst", new DateTime(1991, 11, 8),
                "88 Nanjing Road", "Shanghai", "China", "wei.zhang@example.cn", "+86 21 3456 7890"),
            new("Amina", "Diallo", "HR Manager", new DateTime(1987, 4, 17),
                "12 Rue des Almadies", "Dakar", "Senegal", "a.diallo@example.sn", "+221 33 987 6543"),
            new("Carlos", "Silva", "Sales Executive", new DateTime(1983, 9, 30),
                "Av. Paulista 1000", "Sao Paulo", "Brazil", "c.silva@example.br", "+55 11 98765 4321"),
            new("Priya", "Wijesinghe", " Accounting Manager", new DateTime(1992, 2, 14),
                "25 Galle Road", "Colombo", "Sri Lanka", "priya.w@example.lk", "+94 11 234 5678"),
            new("Kwame", "Osei", "Project Manager", new DateTime(1980, 12, 5),
                "24 Independence Ave", "Accra", "Ghana", "k.osei@example.gh", "+233 30 123 4567"),
            new("María", "Gonzalez", "Owner", new DateTime(1986, 6, 22),
                "Calle 7 #5-20", "Bogota", "Colombia", "m.gonzalez@example.co", "+57 1 654 3210")
        };
    }

    public partial class CustomerInfo : ObservableObject
    {
        [ObservableProperty]
        public string firstName;

        [ObservableProperty]
        public string lastName;

        [ObservableProperty]
        public string title;

        [ObservableProperty]
        public DateTime birthDate;

        [ObservableProperty]
        public string address;

        [ObservableProperty]
        public string city;

        [ObservableProperty]
        public string country;

        [ObservableProperty]
        public string eMail;

        [ObservableProperty]
        public string phone;

        public CustomerInfo(string firstName, string lastName, string title,
                      DateTime birthDate, string address, string city,
                      string country, string eMail, string phone)
        {
            FirstName = firstName;
            LastName = lastName;
            Title = title;
            BirthDate = birthDate;
            Address = address;
            City = city;
            Country = country;
            EMail = eMail;
            Phone = phone;
        }
    }
}
// customer.svg file is placed in the project's `Assets` folder, and its `Build Action` property is set to `AvaloniaResource`.

Создание групп из источника групп

Вы можете заполнить бэнды столбцов из источника бэндов, определенного в модели представления. Используйте свойства DataGridControl.BandsSource и DataGridControl.BandTemplate для создания диапазонов из коллекции бизнес-объектов.

В качестве альтернативы указанию свойства BandTemplate вы можете использовать свойство Styles для инициализации объектов GridBand из бизнес-объектов. Пример смотрите в разделе Инициализация бэндов с использованием стиля .

Чтобы привязать столбцы к диапазонам, установите GridColumn.BandName для каждого столбца на соответствующее название диапазона (GridBand.BandName).

Связанный API

  • DataGridControl.BandsSource — Коллекция бизнес-объектов, используемых для создания корневых бэндов.
  • DataGridControl.BandTemplate — Шаблон, который создает экземпляры GridBand из бизнес-объектов.
  • GridBand.BandsSource — Коллекция бизнес-объектов, используемых для создания дочерних групп.
  • GridBand.BandName — Уникальное имя, используемое для идентификации диапазона и привязывающее его к столбцам.
  • GridColumn.BandName — название группы, связанной с столбцом. Это значение соответствует значению свойства GridBand.BandName.

Пример - Создание групп из источника групп

В следующем примере бэнды создаются из коллекции объектов BandInfo, определенных в модели представления.

Контрол DataGrid отображает коллекцию бизнес-объектов Order. Столбцы сетки автоматически генерируются на основе публичных свойств, предоставляемых классом Order. Обработчик событий AutoGeneratingColumn Data Grid привязывает сгенерированные столбцы к соответствующим диапазонам.

grid-bands-source-example

<!-- MainWindow.axaml -->
<mx:MxWindow xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:DataGridBandSource.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mx="https://schemas.eremexcontrols.net/avalonia"
        xmlns:mxdg="https://schemas.eremexcontrols.net/avalonia/datagrid"
        xmlns:local="using:DataGridBandSource.Views"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="DataGridBandSource.Views.MainWindow"
        x:DataType="vm:MainWindowViewModel"
        Icon="/Assets/EMXControls.ico"
        Title="DataGridBandSource">

    <Design.DataContext>
        <!-- This only sets the DataContext for the previewer in an IDE,
             to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
        <vm:MainWindowViewModel/>
    </Design.DataContext>

    <Border BorderThickness="1" BorderBrush="LightGray" Margin="5">
    <mxdg:DataGridControl Name="dataGrid1" 
                          ItemsSource="{Binding Orders}" 
                          AutoGenerateColumns="True"
                          BandsSource="{Binding BandInfos}"
                          AutoGeneratingColumn="DataGrid1_AutoGeneratingColumn"
                          >
        <mxdg:DataGridControl.BandTemplate>
            <local:DataGridBandTemplate/>
        </mxdg:DataGridControl.BandTemplate>
    </mxdg:DataGridControl>
    </Border>
</mx:MxWindow>
// MainWindow.axaml.cs
using Avalonia.Controls.Templates;
using DataGridBandSource.ViewModels;
using Eremex.AvaloniaUI.Controls.Common;
using Eremex.AvaloniaUI.Controls.DataGrid;

namespace DataGridBandSource.Views;

public partial class MainWindow : MxWindow
{
    public MainWindow()
    {
        this.DataContext = new MainWindowViewModel();
        InitializeComponent();
    }

    private void DataGrid1_AutoGeneratingColumn(object? sender, Eremex.AvaloniaUI.Controls.DataGrid.DataGridControlAutoGeneratingColumnEventArgs e)
    {
        string columnFieldName = e.Column.FieldName.ToLower();
        if (columnFieldName.StartsWith("ship"))
        {
            if (columnFieldName.Contains("country") || columnFieldName.Contains("city"))
                e.Column.BandName = MainWindowViewModel.ShippingAddressBandName;
            else 
                e.Column.BandName = MainWindowViewModel.ShippingStatusBandName;
        }
        else
            e.Column.BandName= MainWindowViewModel.OrderBandName;
    }
}

public class DataGridBandTemplate : ITemplate<object, GridBand>
{
    public GridBand Build(object param)
    {
        var bandInfo = (BandInfo)param;
        var gridBand = new GridBand()
        {
            BandName = bandInfo.Name,
            Header = bandInfo.DisplayName,
            BandsSource = bandInfo.ChildBands,
            HeaderHorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center
        };
        return gridBand;
    }
}
// MainWindowViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;

namespace DataGridBandSource.ViewModels;

public partial class MainWindowViewModel : ViewModelBase
{
    public static string OrderBandName => "Orders";
    public static string ShippingAddressBandName => "ShipAddress";
    public static string ShippingStatusBandName => "ShipStatus";

    [ObservableProperty]
    private ObservableCollection<Order> orders;

    [ObservableProperty]
    private ObservableCollection<BandInfo> bandInfos;

    public MainWindowViewModel()
    {
        Orders = new ObservableCollection<Order>
        {
            new Order(10248, "Queso Cabrales", "Egypt", "Cairo",
                    new DateTime(2023, 7, 4), new DateTime(2023, 7, 16),
                    "Paul Henriot", "Delivered"),
            new Order(10249, "Singaporean Hokkien Fried Mee", "Russia", "Vladivostok",
                    new DateTime(2023, 7, 5), new DateTime(2023, 7, 10),
                    "Robert Schumann", "Delivered"),
            new Order(10252, "Manjimup Dried Apples", "Peru", "Lima",
                    new DateTime(2023, 7, 9), new DateTime(2023, 7, 11),
                    "Yang Wang", "Delivered"),
            new Order(10254, "Wimmers gute Semmelknodel", "Indonesia", "Jakarta",
                    new DateTime(2023, 7, 11), new DateTime(2023, 7, 23),
                    "Shelley Burke", "In Transit")
        };

        BandInfo childBandInfoAddress = new BandInfo(ShippingAddressBandName, "Address", null);
        BandInfo childBandInfoStatus = new BandInfo(ShippingStatusBandName, "Status", null);

        BandInfos = new ObservableCollection<BandInfo>
        {
            new BandInfo(OrderBandName, "Order", null),
            new BandInfo("ShippingInfo", "Shipping Info", new List<BandInfo>{ childBandInfoAddress, childBandInfoStatus })
        };
    }
}

public class BandInfo
{
    public BandInfo(string name, string displayName, IList<BandInfo> childBands)
    {
        this.Name = name;
        this.DisplayName = displayName;
        this.ChildBands = childBands;
    }
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public IList<BandInfo> ChildBands { get; set; }
}

public partial class Order : ObservableObject
{
    [ObservableProperty][property: Display(Order = 0)]
    private int orderId;

    [ObservableProperty][property: Display(Order = 1)]
    private string productName = string.Empty;

    [ObservableProperty][property: Display(Order = 4)]
    private DateTime orderDate;

    [ObservableProperty][property: Display(Order = 5)]
    private string customerName = string.Empty;

    [ObservableProperty][property: Display(Order = 23)]
    private DateTime shippedDate;

    [ObservableProperty][property: Display(Order = 20)]
    private string shipCountry = string.Empty;

    [ObservableProperty][property: Display(Order = 21)]
    private string shipCity = string.Empty;

    [ObservableProperty][property: Display(Order = 24)]
    private string shippingStatus = string.Empty;

    public Order(int orderId, string productName, 
                string shipCountry, string shipCity, DateTime orderDate, DateTime shippedDate,
                string customerName, string shipStatus)
    {
        OrderId = orderId; ProductName = productName;
        ShipCountry = shipCountry; ShipCity = shipCity;
        OrderDate = orderDate; ShippedDate = shippedDate;
        CustomerName = customerName; ShippingStatus = shipStatus;
    }
}

Инициализация бэндов с помощью стиля

В качестве альтернативы указанию свойства BandTemplate вы можете использовать свойство Styles для инициализации объектов GridBand из business objects.

<mxdg:DataGridControl.Styles>
    <Style Selector="mxdg|GridBand">
        <Setter Property="BandName" Value="{Binding Name}"/>
        <Setter Property="Header" Value="{Binding DisplayName}"/>
        <Setter Property="HeaderHorizontalAlignment" Value="Left"/>
    </Style>
</mxdg:DataGridControl.Styles>

Смотрите демонстрацию "Диапазоны столбцов" для примера использования свойств BandsSource и Styles.

Генерация диапазонов на основе атрибутов DataAnnotation (для автоматически генерируемых столбцов)

Этот подход позволяет вам использовать атрибуты для привязывать автоматически сгенерированные столбцы к диапазонам.

Когда включена автоматическая генерация столбцов (см. DataGridControl.AutoGenerateColumns ), контрол Data Grid может инициализировать свойства столбца из определенных атрибутов , применяемых к свойствам бизнес-объекта. Атрибут System.ComponentModel.DataAnnotations.DisplayAttribute позволяет привязывать автоматически сгенерированные столбцы к диапазонам. Укажите параметр DisplayAttribute.GroupName, чтобы определить название диапазона для соответствующего столбца.

public partial class Order : ObservableObject
{
    [ObservableProperty]
    [property: Display(Order = 0, GroupName = "Order")]
    private int orderId;
    //...
}

Когда Data Grid обнаруживает DisplayAttribute.GroupName, он проверяет наличие существующего диапазона с соответствующим именем (GridBand.BandName). Если такой диапазон не найден, он создается и инициализируется следующим образом:

  • Контрол автоматически создает диапазон и устанавливает для его свойства GridBand.BandName значение DisplayAttribute.GroupName.
  • Полоса добавлена в коллекцию DataGridControl.Bands контрола. Вложенные группы добавляются в соответствующие коллекции GridBand.Bands.
  • Созданный диапазон связан с автоматически сгенерированным столбцом, используя свойство GridColumn.BandName.

Параметр DisplayAttribute.GroupName поддерживает вложенные диапазоны. Используйте символ "/" для разделения родительского и дочернего диапазонов (например, "ParentBandName/ChildBandName"). Чтобы включить "/" в качестве буквального символа, используйте двойную косую черту ("//").

Обратите

Individual child band names must be unique throughout the DataGrid control.

public partial class Order : ObservableObject
{
    [ObservableProperty]
    [property: Display(Order = 20, GroupName = "Shipping Info/Address")]
    private string shipCountry = string.Empty;
    //...
}

Связанный API

  • DataGridControl.AutoGenerateBands (по умолчанию — true) - Получает или устанавливает, будут ли автоматически генерироваться диапазоны из атрибутов DisplayAttribute.GroupName, применяемых к свойствам нижележащего бизнес-объекта. Затем эти диапазоны автоматически привязываются к соответствующим автоматически сгенерированным столбцам.

    Автоматическая генерация диапазонов (и привязка диапазонов к автоматически сгенерированным столбцам) принудительно отключена, если DataGridControl.AutoGenerateColumns является false.

  • DataGridControl.Bands и GridBand.Bands — Вы можете использовать эти коллекции для доступа к автоматически сгенерированным диапазонам.

Пример - Создание групп на основе атрибута DisplayAttribute.Параметр GroupName

В этом примере контрол DataGrid отображает список объектов Order. Опция AutoGenerateColumns позволяет автоматически генерировать столбцы из публичных свойств класса Order. Диапазоны генерируются на основе атрибута System.ComponentModel.DataAnnotations.DisplayAttribute, применяемого к свойствам класса Order.

datagrid-bands-from-attributes-example

Параметр DisplayAttribute.GroupName определяет имена диапазонов для автоматически сгенерированных столбцов.

<!-- MainWindow.axaml -->
<mx:MxWindow xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:DataGridBandsFromAttributes.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mx="https://schemas.eremexcontrols.net/avalonia"
        xmlns:mxdg="https://schemas.eremexcontrols.net/avalonia/datagrid"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="DataGridBandsFromAttributes.Views.MainWindow"
        x:DataType="vm:MainWindowViewModel"
        Icon="/Assets/EMXControls.ico"
        Title="DataGridBandsFromAttributes">

    <Design.DataContext>
        <!-- This only sets the DataContext for the previewer in an IDE,
             to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
        <vm:MainWindowViewModel/>
    </Design.DataContext>

    <Grid RowDefinitions="Auto" ColumnDefinitions="Auto" >
        <Border BorderThickness="1" BorderBrush="LightGray" Margin="10">
            <mxdg:DataGridControl Name="dataGrid1"
                                  ItemsSource="{Binding Orders}"
                                  AutoGenerateColumns="True"
                          >
                <mxdg:DataGridControl.Styles>
                    <Style Selector="mxdg|GridBand">
                        <Setter Property="HeaderHorizontalAlignment" Value="Center"/>
                    </Style>
                </mxdg:DataGridControl.Styles>
            </mxdg:DataGridControl>
        </Border>
    </Grid>
</mx:MxWindow>
// MainWindowViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;

namespace DataGridBandsFromAttributes.ViewModels;

public partial class MainWindowViewModel : ViewModelBase
{
    [ObservableProperty]
    private ObservableCollection<Order> orders;

    public MainWindowViewModel()
    {
        Orders = new ObservableCollection<Order>
        {
            new(10424, "Brazilian Coffee Beans", "Brazil", "Sao Paulo",
                new DateTime(2023, 9, 16), new DateTime(2023, 9, 25),
                "Carlos Silva", "Delivered"),

            new(10425, "Thai Silk Cushions", "Thailand", "Bangkok",
                new DateTime(2023, 9, 17), new DateTime(2023, 9, 26),
                "Somsak Chai", "Shipped")
        };
    }
}


public partial class Order : ObservableObject
{
    [ObservableProperty][property: Display(Order = 0, GroupName = "Details")]
    private int orderId;

    [ObservableProperty][property: Display(Order = 1, GroupName = "Details")]
    private string productName = string.Empty;

    [ObservableProperty][property: Display(Order = 4, GroupName = "Details")]
    private DateTime orderDate;

    [ObservableProperty][property: Display(Order = 5, GroupName = "Customer")]
    private string customerName = string.Empty;

    [ObservableProperty][property: Display(Order = 23, GroupName ="Shipping Information/Status")]
    private DateTime shippedDate;

    [ObservableProperty][property: Display(Order = 20, GroupName = "Shipping Information/Address")]
    private string shipCountry = string.Empty;

    [ObservableProperty][property: Display(Order = 21, GroupName = "Shipping Information/Address")]
    private string shipCity = string.Empty;

    [ObservableProperty][property: Display(Order = 24, GroupName = "Shipping Information/Status")]
    private string shippingStatus = string.Empty;

    public Order(int orderId, string productName, 
                string shipCountry, string shipCity, DateTime orderDate, DateTime shippedDate,
                string customerName, string shipStatus)
    {
        OrderId = orderId; ProductName = productName;
        ShipCountry = shipCountry; ShipCity = shipCity;
        OrderDate = orderDate; ShippedDate = shippedDate;
        CustomerName = customerName; ShippingStatus = shipStatus;
    }
}

Порядок расположения столбцов и полос

Контрол DataGrid размещает столбцы в соответствии с их свойствами GridColumn.VisibleIndex.

Порядок заголовков полос определяется визуальным порядком расположения столбцов. Если столбцы, связанные с одним и тем же диапазоном, расположены рядом друг с другом, заголовки их диапазонов объединяются.

<mxdg:DataGridControl.Columns>
    <mxdg:GridColumn Width="*" FieldName="FirstName" BandName="Customer"/>
    <mxdg:GridColumn Width="*" FieldName="LastName" BandName="Customer"/>
    <mxdg:GridColumn Width="*" FieldName="Address" BandName="Details"/>
</mxdg:DataGridControl.Columns>
datagrid-bands-merged-band-header

Контрол не перестраивает столбцы автоматически, чтобы сгруппировать их по диапазонам. Если столбцы, связанные с одним и тем же диапазоном, размещены в несмежных позициях (разделенных столбцами, связанными с разными диапазонами), контрол DataGrid создает несколько заголовков диапазонов с одинаковыми именами над заголовками столбцов.

В следующем фрагменте кода столбцы, связанные с диапазоном Customer, разделены столбцом Address, который связан с диапазоном Details. Контрол не изменяет автоматически порядок столбцов, чтобы объединить их в один диапазон Customer:

<mxdg:DataGridControl.Columns>
    <mxdg:GridColumn Width="*" FieldName="FirstName" BandName="Customer"/>
    <mxdg:GridColumn Width="*" FieldName="LastName" BandName="Customer"/>
    <mxdg:GridColumn Width="*" FieldName="Address" BandName="Details"/>
    <mxdg:GridColumn Width="*" FieldName="Title" BandName="Customer"/>
</mxdg:DataGridControl.Columns>

datagrid-bands-not-keep-columns-together

Операции перетаскивания

Перетаскивание столбцов

Пользователи могут свободно перетаскивать столбцы внутри контрола, если DataGridControl.AllowColumnMoving равен true (по умолчанию). Если они перетаскивают столбец в другой диапазон, контрол рисует соответствующий заголовок диапазона (GridColumn.BandHeader) над этим столбцом в его новой позиции. Смотрите Порядок расположения столбцов и полос .

Связанный API

  • DataGridControl.AllowColumnMoving — Возвращает или устанавливает, включены ли операции перетаскивания столбцов.

Перетаскивание группы

DataGrid не поддерживает операции перетаскивания в диапазонах.

Отображение и скрытие панели групп

На панели диапазонов отображаются заголовки диапазонов. Панель видна, когда любой столбец связан с существующей полосой. Используйте следующее свойство, чтобы принудительно скрыть панель band, когда это необходимо:

  • DataGridControl.ShowBands — Определяет, будет ли видна панель диапазонов.

Укажите содержимое заголовка группы

  • Header — Возвращает или задает содержимое заголовка группы. Если это свойство не задано, в группе отображается значение свойства GridBand.BandName.
  • HeaderTemplate — Получает или задает шаблон, используемый для отображения объекта Header. Шаблон позволяет отображать картинки и пользовательские контролы, а также отображать текст произвольным способом.

Пример - Отображение картинки в заголовке группы

В следующем примере отображается картинка в формате SVG, за которой следует текстовая подпись в заголовке группы. Картинка в формате SVG (файл customer.svg) найдена в папке проекта Assets, а для свойства Build Action установлено значение AvaloniaResource.

grid-bandheader-ImageAndText

xmlns:svg="using:Avalonia.Svg.Skia"

<mxdg:DataGridControl.Bands>
    <mxdg:GridBand BandName="Customer" HeaderHorizontalAlignment="Center">
        <mxdg:GridBand.HeaderTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <svg:Svg Path="/Assets/customer.svg" Width="16" Height="16" Margin="5" />
                    <TextBlock Text="{Binding}" VerticalAlignment="Center"/>
                </StackPanel>
            </DataTemplate>
        </mxdg:GridBand.HeaderTemplate>
</mxdg:DataGridControl.Bands>

Пустой заголовок полосы

Столбцы, не связанные с существующими диапазонами, отображаются под пустым заголовком диапазона.

<mxdg:DataGridControl.Columns>
    <mxdg:GridColumn Width="*" FieldName="Address" BandName="Details"/>
    <mxdg:GridColumn Width="*" FieldName="City" BandName="Details"/>
    <mxdg:GridColumn Width="*" FieldName="Title"/>
</mxdg:DataGridControl.Columns>    

datagrid-bands-blank-band

Разделители полос

  • DataGridControl.ShowBandSeparators — Позволяет использовать толстые разделители между соседними полосами. Используйте это свойство, чтобы подчеркнуть различия между полосами. Если ShowBandSeparators отключен, сетка рисует обычные разделители столбцов (тонкие линии) между полосами.

    На следующей картинке показаны разделители полос.

    datagrid-band-separators

Скрыть группы

Объекты Band не обладают свойством "Visible". Чтобы скрыть группу, вам следует скрыть столбцы, связанные с этой группой.

Полосы без связанных столбцов никогда не отображаются.

Всплывающие подсказки для заголовков групп

Используйте свойство HeaderToolTip, чтобы указать пользовательские подсказки для заголовков бэндов. Пользовательские подсказки отображаются при наведении курсора мыши на заголовки бэндов независимо от того, обрезан текст заголовка бэнда или нет.

<mxdg:GridBand BandName="Details" HeaderHorizontalAlignment="Center" HeaderToolTip="Contact and location information">

grid-band-headertooltip

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



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