Начало работы с контролом ListView¶
ListViewControl позволяет отображать список элементов в одном или нескольких столбцах. Контрол поддерживает сортировку элементов, группировку, фильтрацию и множественный выбор.
В этом руководстве показано, как использовать контрол ListViewControl
для реализации списка элементов, а также сортировать и группировать элементы по свойствам элемента.
Контрол ListView может быть заполнен элементами из источника объекта. Чтобы отобразить связанные элементы, вам необходимо предоставить шаблон элемента. При использовании контрола ListView вы можете создавать сложные шаблоны элементов, состоящие из нескольких полей. В этом примере создается шаблон элемента, который определяет границу с картинкой SVG и текстовыми блоками внутри.
Создание нового приложения¶
Создайте новое Eremex Avalonia .NET MVVM-приложение . Назовите его ListView-example.
Чтобы отобразить картинки в формате SVG, добавьте пакет NuGet Avalonia.Svg.Skia
в проект.
Определите источник объекта¶
В файле MainWindowViewModel.cs создайте класс ItemViewModel, который инкапсулирует объект элемента.
public partial class ItemViewModel : ObservableObject
{
[ObservableProperty] private int invoiceId;
[ObservableProperty] private string shipCountry;
[ObservableProperty] private DateTime date;
[ObservableProperty] private IImage flag;
public ItemViewModel(int id, string shipCountry, IImage flag)
{
InvoiceId = id;
ShipCountry = shipCountry;
Random random = new Random();
Date = new DateTime(DateTime.Now.Year, random.Next(1, 12), random.Next(1, 28));
Flag = flag;
}
}
Свойства InvoiceId, Date и Flag, предоставляемые классом ItemViewModel, содержат значения для отображения в элементах ListView. Свойство ItemViewModel.ShipCountry указывает страну доставки, связанную с элементом. Элементы ListView будут сгруппированы по этому свойству.
Создайте и инициализируйте коллекцию Items в классе MainWindowViewModel, как показано ниже. Следующий код заполняет коллекцию Items тремя наборами элементов. Каждый набор элементов связан со своей собственной страной доставки (China, Brazil и India).
using CommunityToolkit.Mvvm.ComponentModel;
using Avalonia.Svg.Skia;
using Eremex.AvaloniaUI.Controls.Utils;
public partial class MainWindowViewModel : ViewModelBase
{
[ObservableProperty]
private List<ItemViewModel> items;
public MainWindowViewModel()
{
SvgImage chinaFlag = ImageLoader.LoadSvgImage(Assembly.GetExecutingAssembly(), "Assets/china-flag.svg");
SvgImage indiaFlag = ImageLoader.LoadSvgImage(Assembly.GetExecutingAssembly(), "Assets/india-flag.svg");
SvgImage brazilFlag = ImageLoader.LoadSvgImage(Assembly.GetExecutingAssembly(), "Assets/brazil-flag.svg");
Random random = new Random();
Items = new List<ItemViewModel>();
for (int i = 1; i < 10; i++)
{
Items.Add(new ItemViewModel(random.Next(500), "China", chinaFlag));
}
for (int i = 1; i < 5; i++)
{
Items.Add(new ItemViewModel(random.Next(500), "Brazil", brazilFlag));
}
for (int i = 1; i < 8; i++)
{
Items.Add(new ItemViewModel(random.Next(500), "India", indiaFlag));
}
}
}
Метод Eremex.AvaloniaUI.Controls.Utils.ImageLoader.LoadSvgImage
используется для загрузки SVG-картинок, хранящихся в определенной папке текущего проекта. Предполагается, что картинки SVG помещены в папку Assets, и их свойству Build Action
присвоено значение AvaloniaResource
. Убедитесь, что пакет Avalonia.Svg.Skia
включен в проект.
Создание контрола ListView¶
Откройте файл MainWindow.axaml и определите компонент ListViewControl
в XAML.
xmlns:mxlv="https://schemas.eremexcontrols.net/avalonia/listview"
<mxlv:ListViewControl Name="listViewControl1">
</mxlv:ListViewControl>
Привязать ListView к коллекции элементов¶
Убедитесь, что для DataContext главного окна и, следовательно, для DataContext ListView задан объект MainWindowViewModel. Смотрите файл App.axaml.cs, который присваивает DataContext главному окну.
Привяжите ListView к коллекции элементов, определенных в классе MainWindowViewModel, используя свойство ListViewControl.ItemsSource
.
<mxlv:ListViewControl Name="listViewControl1" ItemsSource="{Binding Items}">
</mxlv:ListViewControl>
Определите шаблон элемента¶
Для элементов в контроле ListView отсутствует дефолтная отрисовка. Чтобы отобразить элементы определенным образом, укажите шаблон элемента из свойства ListViewControl.ItemTemplate
.
В приведенном ниже коде шаблон элемента определяет ограниченный объект сетки с двумя текстовыми блоками и картинкой внутри. Текстовые блоки отображают значения свойств ItemViewModel.InvoiceId и ItemViewModel.Date соответственно. Контрол картинки привязан к свойству __ItemViewModel.Flag_, в котором хранится картинка в формате SVG.
<mxlv:ListViewControl Name="listViewControl1" ItemsSource="{Binding Items}">
<mxlv:ListViewControl.ItemTemplate>
<DataTemplate DataType="vm:ItemViewModel">
<Border BorderBrush="DarkGray" BorderThickness="1">
<Grid RowDefinitions="2*, *" Margin="3">
<TextBlock Text="{Binding InvoiceId, StringFormat={}Invoice: {0}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<DockPanel Grid.Row="1" VerticalAlignment="Center">
<TextBlock Text="{Binding Date, StringFormat=yyyy-MM-dd}" FontSize="8" DockPanel.Dock="Left"/>
<Image Width="20" DockPanel.Dock="Right" Source="{Binding Flag}"/>
</DockPanel>
</Grid>
</Border>
</DataTemplate>
</mxlv:ListViewControl.ItemTemplate>
</mxlv:ListViewControl>
Укажите размер элемента¶
Контрол ListView вычисляет размер элемента по умолчанию для первого элемента и применяет его к другим элементам. Таким образом, все элементы ListView имеют одинаковый размер отображения.
Если размер элемента по умолчанию не соответствует вашим потребностям, вы можете использовать свойства ListViewControl.ItemWidth
и ListViewControl.ItemHeight
, чтобы указать пользовательский размер элемента. Приведенный ниже код применяет пользовательский размер элемента к элементам ListView.
<mxlv:ListViewControl Name="listViewControl1" ItemsSource="{Binding Items}"
ItemHeight="70" ItemWidth="100">
Групповые элементы¶
Вы можете сортировать и/или группировать элементы ListView по неограниченному количеству свойств элемента. Когда вы группируете по свойству, создаются групповые строки, объединяющие элементы. Обратите внимание, что групповые строки автоматически сортируются по свойству group.
Коллекция ListViewControl.SortInfo
определяет свойства элемента, используемые для сортировки и группировки элементов.
Чтобы сгруппировать элементы, выполните следующие действия:
- Добавьте объект(ы)
ListViewSortInfo
в коллекциюListViewControl.SortInfo
. Установите для элементаListViewSortInfo.FieldName
значение свойства элемента, по которому следует группировать элементы. При необходимости используйте свойствоListViewSortInfo.SortDirection
, чтобы выбрать между порядком сортировки по возрастанию и по убыванию, в котором будут размещены группирующие строки. - Задайте свойству
ListViewControl.GroupCount
значение number of group levels (групповые свойства).ListViewControl.GroupCount
указывает, сколько объектовListViewSortInfo
, начиная с начала коллекцииListViewControl.SortInfo
, используется для группировки данных. Если вы группируете по одному свойству, установите дляGroupCount
значение1
. Если вы группируете по двум свойствам, установите дляGroupCount
значение2
и так далее.
Следующий код реализует группировку элементов по свойству ShipCountry:
<mxlv:ListViewControl Name="listViewControl1" ItemsSource="{Binding Items}"
ItemHeight="40" ItemWidth="60"
GroupCount="1">
<mxlv:ListViewControl.SortInfo>
<mxlv:ListViewSortInfo FieldName="ShipCountry" SortDirection="Ascending" />
</mxlv:ListViewControl.SortInfo>
<!-- ... -->
</mxlv:ListViewControl>
Сортировка элементов¶
Давайте отсортируем элементы в каждой группе по свойству элемента Date в порядке убывания. Для этой цели добавьте новый объект ListViewSortInfo
в коллекцию ListViewControl.SortInfo
и установите для его элементов ListViewSortInfo.FieldName
и ListViewSortInfo.SortDirection
соответствующие значения.
<mxlv:ListViewControl.SortInfo>
<mxlv:ListViewSortInfo FieldName="ShipCountry" SortDirection="Ascending" />
<mxlv:ListViewSortInfo FieldName="Date" SortDirection="Descending" />
</mxlv:ListViewControl.SortInfo>
Поскольку свойству ListViewControl.GroupCount
присвоено значение 1
, первый объект ListViewSortInfo
в коллекции ListViewControl.SortInfo
указывает поле, используемое для группировки данных. Второй объект ListViewSortInfo
относится к полю, используемому только для сортировки данных.
Выберите режим расположения элементов¶
ListView поддерживает два режима расположения элементов, которые вы можете выбрать с помощью свойства ListViewControl.ItemLayoutMode
:
-
ListViewItemLayoutMode.Wrap
(по умолчанию) — элементы размещены поперек, а затем вниз. Они автоматически обтекаются по правому краю контрола, создавая несколько линий. -
ListViewItemLayoutMode.Stack
— Элементы размещены в вертикальном списке. Они растягиваются, подгоняя их под ширину LayoutView.
В этом руководстве мы будем придерживаться режима размещения Wrap
по умолчанию.
Получить сфокусированный (выбранный) Элемент¶
Когда пользователь щелкает по определенному элементу с помощью мыши или клавиатуры в режиме выбора одного элемента, фокусируемый элемент изменяется. Вы можете использовать свойство ListViewControl.FocusedItem
или ListViewControl.FocusedItemIndex
для идентификации сфокусированного элемента.
Следующий код определяет свойство FocusedItem в модели основного представления и привязывает элемент ListViewControl.FocusedItem
к этому свойству.
//MainWindowViewModel.cs
public partial class MainWindowViewModel : ViewModelBase
{
//...
ItemViewModel focusedItem;
ItemViewModel FocusedItem {
get {
return focusedItem;
}
set
{
if (value != focusedItem)
{
focusedItem = value;
// Perform actions when the focused item changes.
}
}
}
}
<!-- MainWindow.axaml -->
<mxlv:ListViewControl Name="listViewControl1" ItemsSource="{Binding Items}"
ItemHeight="70" ItemWidth="100"
GroupCount="1"
FocusedItem="{Binding FocusedItem, Mode=TwoWay}"
>
Чтобы разрешить одновременный выбор нескольких элементов, установите для свойства ListViewControl.SelectionMode
значение Multiple
. В этом случае вы можете извлечь выбранные элементы из коллекции ListViewControl.SelectedItems
.
Результат¶
Вы можете создать и запустить приложение, чтобы увидеть следующий результат:
Полный код¶
MainWindow.axaml:
<mx:MxWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ListView_example.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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ListView_example.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/EMXControls.ico"
Title="ListView_example"
xmlns:mxlv="https://schemas.eremexcontrols.net/avalonia/listview"
>
<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 BorderBrush="LightGray" BorderThickness="1" Margin="5">
<mxlv:ListViewControl Name="listViewControl1" ItemsSource="{Binding Items}"
ItemHeight="70" ItemWidth="100"
GroupCount="1"
FocusedItem="{Binding FocusedItem, Mode=TwoWay}" SelectionMode="Multiple" SelectedItems=""
>
<mxlv:ListViewControl.SortInfo>
<mxlv:ListViewSortInfo FieldName="ShipCountry" SortDirection="Ascending" />
<mxlv:ListViewSortInfo FieldName="Date" SortDirection="Descending" />
</mxlv:ListViewControl.SortInfo>
<mxlv:ListViewControl.ItemTemplate>
<DataTemplate DataType="vm:ItemViewModel">
<Border BorderBrush="DarkGray" BorderThickness="1">
<Grid RowDefinitions="2*, *" Margin="3">
<TextBlock Text="{Binding InvoiceId, StringFormat={}Invoice: {0}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<DockPanel Grid.Row="1" VerticalAlignment="Center">
<TextBlock Text="{Binding Date, StringFormat=yyyy-MM-dd}" FontSize="8" DockPanel.Dock="Left"/>
<Image Width="20" DockPanel.Dock="Right" Source="{Binding Flag}"/>
</DockPanel>
</Grid>
</Border>
</DataTemplate>
</mxlv:ListViewControl.ItemTemplate>
</mxlv:ListViewControl>
</Border>
</mx:MxWindow>
MainWindowViewModel.cs:
using Avalonia.Media;
using Avalonia.Svg.Skia;
using CommunityToolkit.Mvvm.ComponentModel;
using Eremex.AvaloniaUI.Controls.ListView;
using Eremex.AvaloniaUI.Controls.Utils;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml.Linq;
namespace ListView_example.ViewModels;
public partial class MainWindowViewModel : ViewModelBase
{
[ObservableProperty]
private List<ItemViewModel> items;
public MainWindowViewModel()
{
SvgImage chinaFlag = ImageLoader.LoadSvgImage(Assembly.GetExecutingAssembly(), "Assets/china-flag.svg");
SvgImage indiaFlag = ImageLoader.LoadSvgImage(Assembly.GetExecutingAssembly(), "Assets/india-flag.svg");
SvgImage brazilFlag = ImageLoader.LoadSvgImage(Assembly.GetExecutingAssembly(), "Assets/brazil-flag.svg");
Random random = new Random();
Items = new List<ItemViewModel>();
for (int i = 1; i < 10; i++)
{
Items.Add(new ItemViewModel(random.Next(500), "China", chinaFlag));
}
for (int i = 1; i < 5; i++)
{
Items.Add(new ItemViewModel(random.Next(500), "Brazil", brazilFlag));
}
for (int i = 1; i < 8; i++)
{
Items.Add(new ItemViewModel(random.Next(500), "India", indiaFlag));
}
// Set focus to the first item in the item collection.
focusedItem = Items[0];
}
ItemViewModel focusedItem;
ItemViewModel FocusedItem {
get {
return focusedItem;
}
set
{
if (value != focusedItem)
{
focusedItem = value;
// Perform actions when the focused item changes.
}
}
}
}
public partial class ItemViewModel : ObservableObject
{
[ObservableProperty] private int invoiceId;
[ObservableProperty] private string shipCountry;
[ObservableProperty] private DateTime date;
[ObservableProperty] private IImage flag;
public ItemViewModel(int id, string shipCountry, IImage flag)
{
InvoiceId = id;
ShipCountry = shipCountry;
Random random = new Random();
Date = new DateTime(DateTime.Now.Year, random.Next(1, 12), random.Next(1, 28));
Flag = flag;
}
}
Картинки *.svg, используемые в этом руководстве, помещены в папку Assets проекта. У них для свойства Build Action
установлено значение AvaloniaResource
.
* Эта страница была создана автоматически с помощью сервиса машинного перевода Яндекс Переводчик.