Диапазоны (Бэнды)¶
Вы можете использовать диапазоны для визуального объединения столбцов вместе. Контрол DataGrid отображает диапазоны как дополнительные заголовки над заголовками столбцов. Как заголовки диапазонов, так и заголовки столбцов могут содержать текст, изображения или пользовательское содержимое. Вы также можете создавать иерархические диапазоны с неограниченным количеством уровней вложенности.
На следующем изображении показан контрол DataGrid с четырьмя диапазонами: 'Customer', 'Details', 'Address' и 'Contact':

Следующие подходы позволяют генерировать диапазоны столбцов:
- Создание диапазонов вручную
- Создание диапазонов из источника диапазонов
- Создание диапазонов на основе атрибутов DataAnnotation (для автоматически генерируемых столбцов)
Создание диапазонов вручную¶
Выполните следующие шаги для ручного создания диапазонов:
- 
Создайте объекты диапазонов (экземпляры класса GridBand) и добавьте их в коллекциюDataGridControl.Bands.Присвойте созданным диапазонам уникальные имена с помощью свойства GridBand.BandName.<mxdg:DataGridControl.Bands> <mxdg:GridBand BandName="Customer" HeaderHorizontalAlignment="Center"/> <mxdg:GridBand BandName="Details" HeaderHorizontalAlignment="Center"/> </mxdg:DataGridControl.Bands>Вы можете создать иерархическую структуру диапазонов. Чтобы создать вложенные диапазоны: - В code-behind: Добавьте диапазоны в коллекцию 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.
- В code-behind: Добавьте диапазоны в коллекцию 
- 
Свяжите столбцы с конкретными диапазонами, установив для каждого столбца свойство GridColumn.BandNameв соответствие с именем диапазона (GridBand.BandName).
Столбцы располагаются в контроле DataGrid в соответствии с их свойствами GridColumn.VisibleIndex.
Контрол не переупорядочивает столбцы автоматически, чтобы сгруппировать их по диапазонам.

См. Порядок столбцов и диапазонов
Связанный API¶
- GridBandclass — Инкапсулирует диапазон столбцов.
- GridBand.BandName— Уникальное имя, используемое для идентификации диапазона и связи его со столбцами.
- GridColumn.BandName— Имя диапазона, связанного со столбцом. Это значение соответствует значению свойства- GridBand.BandName.
- DataGridControl.Bands— Коллекция корневых диапазонов.
- GridBand.Bands— Коллекция дочерних диапазонов для этого диапазона.
Пример - Создание диапазонов столбцов в контроле DataGrid вручную¶
Следующий пример создает диапазоны и назначает их столбцам, как показано на изображении ниже:

- Диапазоны "Customer", "Address" и "Contact" связаны со столбцами грида.
- Диапазон "Details" содержит два вложенных диапазона ("Address" и "Contact"). Этот диапазон не связан напрямую со столбцами.
Каждому диапазону присвоено уникальное имя с помощью свойства 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`.
Генерация диапазонов из источника диапазонов¶
Вы можете заполнять диапазоны столбцов из источника диапазонов, определенного в View Model. Используйте свойства 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, определенных в View Model.
Контрол DataGrid отображает коллекцию бизнес-объектов Order. Столбцы грида автоматически генерируются из открытых свойств, предоставляемых классом Order. Обработчик события AutoGeneratingColumn data grid связывает сгенерированные столбцы с соответствующими диапазонами.

<!-- 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 из бизнес-объектов.
<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>
См. демо "Column Bands" для примера использования свойств 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"). Чтобы включить '/' как литеральный символ, используйте нотацию с двойным слэшем ("//").
Замечание
Отдельные имена дочерних диапазонов должны быть уникальными во всем контроле DataGrid.
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.

Параметр 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 создает несколько заголовков диапазонов с одинаковым именем над заголовками столбцов.
В следующем фрагменте кода столбцы, связанные с диапазоном 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>

Операции перетаскивания¶
Перетаскивание столбцов¶
Пользователи могут свободно перетаскивать столбцы внутри контрола, если DataGridControl.AllowColumnMoving равно true (по умолчанию). Если они перетащат столбец в другой диапазон, контрол нарисует соответствующий заголовок диапазона (GridColumn.BandHeader) над этим столбцом в его новой позиции. См. Порядок столбцов и диапазонов.
Связанный API¶
- DataGridControl.AllowColumnMoving— Получает или задает, включены ли операции перетаскивания столбцов.
Перетаскивание диапазонов¶
DataGrid не поддерживает операции перетаскивания для диапазонов.
Отображение и скрытие панели диапазонов¶
Панель диапазонов отображает заголовки диапазонов. Панель видима, когда любой столбец связан с существующим диапазоном. Используйте следующее свойство для принудительного скрытия панели диапазонов, когда это требуется:
- DataGridControl.ShowBands— Получает или задает, видима ли панель диапазонов.
Указание содержимого заголовка диапазона¶
- Header— Получает или задает содержимое заголовка диапазона. Если это свойство не задано, диапазон отображает значение свойства- GridBand.BandName.
- HeaderTemplate— Получает или задает шаблон, используемый для отображения объекта- Header. Шаблон позволяет отображать изображения и пользовательские контролы, а также выводить текст пользовательским способом.
Пример - Отображение изображения в заголовке диапазона¶
Следующий пример отображает изображение SVG с последующей текстовой подписью в заголовке диапазона. Изображение SVG (файл customer.svg) находится в папке Assets проекта, а его свойство Build Action установлено в AvaloniaResource.

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:GridBand>
</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>    

Разделители диапазонов¶
- 
DataGridControl.ShowBandSeparators— Включает толстые разделители между смежными диапазонами. Используйте это свойство, чтобы подчеркнуть разделение между диапазонами. ЕслиShowBandSeparatorsотключен, грид рисует обычные разделители столбцов (тонкие линии) между диапазонами.На следующем изображении показаны разделители диапазонов.  
Скрытие диапазонов¶
Объекты диапазонов не имеют свойства 'Visible'. Чтобы скрыть диапазон, вы должны скрыть столбцы, связанные с этим диапазоном.
Диапазоны без связанных столбцов никогда не отображаются.
Всплывающие подсказки для заголовков диапазонов¶
Используйте свойство HeaderToolTip, чтобы указать пользовательские всплывающие подсказки для заголовков диапазонов. Пользовательские подсказки отображаются при наведении на заголовки диапазонов, независимо от того, обрезан ли текст заголовка диапазона или нет.
<mxdg:GridBand BandName="Details" HeaderHorizontalAlignment="Center" HeaderToolTip="Contact and location information">

Когда пользовательская подсказка не назначена диапазону, стандартная подсказка показывается для заголовка диапазона в случае, если текст заголовка обрезан. Стандартная подсказка отображает полный, необрезанный текст заголовка.
* Эта страница была переведена с помощью нейросети Deepseek.