Далее рассмотрим элементы отображения для множества записей. Они часто используются для вывода наборов данных в виде вертикального списка, сетки или таблицы.
| Элемент управления | Описание |
|---|---|
| ListView | Виртуализированный вертикальный список |
| ListViewItem | Элемент списка ListView |
| GridView | Сеточное отображение карточек (плитки/изображения) |
| GridViewItem | Плитка для GridView |
| ItemsRepeater | Настраиваемый высокоэффективный контейнер повторяющихся элементов |
| ItemsStackPanel | Виртуализированная вертикальная панель компоновки |
| ItemsWrapGrid | Виртуализированная сеточная панель с автоматическим переносом строк |
| LinedFlowLayout | Потоковое расположение текста с изображениями |
Добавление элементов управления в XAML
Сначала отредактируйте разметку XAML. Если страница не является окном Window, используйте пример ниже как образец.
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="AppWinui.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppWinui"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="AppWinui">
<ScrollViewer VerticalScrollMode="Auto" Padding="16" Background="#F7F8FA">
<StackPanel Spacing="36">
<!-- 1. ListView + ListViewItem + ItemsStackPanel -->
<StackPanel>
<TextBlock Text="1. ListView (ItemsStackPanel)" FontSize="17" FontWeight="SemiBold"/>
<ListView Height="180" Margin="0 8 0 0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListViewItem Background="White" Padding="10">
<StackPanel Orientation="Horizontal" Spacing="10">
<Ellipse Width="36" Height="36" Fill="#4285F4"/>
<TextBlock Text="Элемент 1" FontSize="15" VerticalAlignment="Center"/>
</StackPanel>
</ListViewItem>
<ListViewItem Background="White" Padding="10">
<StackPanel Orientation="Horizontal" Spacing="10">
<Ellipse Width="36" Height="36" Fill="#EA4335"/>
<TextBlock Text="Элемент 2" FontSize="15" VerticalAlignment="Center"/>
</StackPanel>
</ListViewItem>
<ListViewItem Background="White" Padding="10">
<StackPanel Orientation="Horizontal" Spacing="10">
<Ellipse Width="36" Height="36" Fill="#FBBC05"/>
<TextBlock Text="Элемент 3" FontSize="15" VerticalAlignment="Center"/>
</StackPanel>
</ListViewItem>
</ListView>
</StackPanel>
<!-- 2. GridView + GridViewItem + ItemsWrapGrid -->
<StackPanel>
<TextBlock Text="2. GridView (ItemsWrapGrid)" FontSize="17" FontWeight="SemiBold"/>
<GridView Height="220" Margin="0 8 0 0">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid ItemWidth="120" ItemHeight="140"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridViewItem Margin="4" Background="White" CornerRadius="6" Padding="8">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="6">
<Rectangle Width="70" Height="70" Fill="#FF7A7A" />
<TextBlock Text="Плитка 1" FontSize="14"/>
</StackPanel>
</GridViewItem>
<GridViewItem Margin="4" Background="White" CornerRadius="6" Padding="8">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="6">
<Rectangle Width="70" Height="70" Fill="#48CFC0" />
<TextBlock Text="Плитка 2" FontSize="14"/>
</StackPanel>
</GridViewItem>
<GridViewItem Margin="4" Background="White" CornerRadius="6" Padding="8">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="6">
<Rectangle Width="70" Height="70" Fill="#FFD470" />
<TextBlock Text="Плитка 3" FontSize="14"/>
</StackPanel>
</GridViewItem>
<GridViewItem Margin="4" Background="White" CornerRadius="6" Padding="8">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="6">
<Rectangle Width="70" Height="70" Fill="#8A3797" />
<TextBlock Text="Плитка 4" FontSize="14"/>
</StackPanel>
</GridViewItem>
</GridView>
</StackPanel>
<!-- 3. ItemsRepeater + StackLayout (ItemsStackPanel) -->
<StackPanel>
<TextBlock Text="3. ItemsRepeater - StackLayout" FontSize="17" FontWeight="SemiBold"/>
<ItemsRepeater Height="160" Margin="0 8 0 0" ItemsSource="{x:Bind ListData}">
<ItemsRepeater.Layout>
<StackLayout/>
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="x:String">
<Border Background="White" Margin="3" Padding="8" CornerRadius="5">
<StackPanel Orientation="Horizontal" Spacing="8">
<FontIcon Glyph="" FontSize="22" Foreground="#0078D4"/>
<TextBlock Text="{x:Bind}" FontSize="15" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</StackPanel>
<!-- 4. ItemsRepeater + ItemsWrapGrid -->
<StackPanel>
<TextBlock Text="4. ItemsRepeater + панель ItemsWrapGrid" FontSize="17" FontWeight="SemiBold"/>
<ItemsRepeater Height="200" Margin="0 8 0 0" ItemsSource="{x:Bind GridData}">
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="x:String">
<Border Background="#EFF5FF" Margin="4" CornerRadius="6">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="4">
<FontIcon Glyph="" FontSize="28" Foreground="#2463EB"/>
<TextBlock Text="{x:Bind}" FontSize="13"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</StackPanel>
<!-- 5. ItemsRepeater + LinedFlowLayout -->
<StackPanel>
<TextBlock Text="5. ItemsRepeater - LinedFlowLayout" FontSize="17" FontWeight="SemiBold"/>
<ItemsRepeater Height="240" Margin="0 8 0 0" ItemsSource="{x:Bind FlowData}">
<ItemsRepeater.Layout>
<LinedFlowLayout LineHeight="80"/>
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="x:String">
<Border Background="White" Padding="10" Margin="3" CornerRadius="5" BorderBrush="#E0E2E6" BorderThickness="1">
<StackPanel Orientation="Horizontal" Spacing="8">
<Rectangle Width="50" Height="50" Fill="#10B981"/>
<TextBlock Text="{x:Bind}" FontSize="13" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Window>
Code language: C++ (cpp)
Здесь мы используем ItemsSource для привязки источников данных, наборы данных создаются в бэкенд-коде C++, например ItemsSource=»{x:Bind FlowData}».
Добавление свойств в IDL-файл
Добавьте три привязываемых свойства: ListData, GridData, FlowData
namespace AppWinui
{
[default_interface]
runtimeclass MainWindow : Microsoft.UI.Xaml.Window
{
MainWindow();
Int32 MyProperty;
Windows.Foundation.Collections.IObservableVector<String> ListData{ get; };
Windows.Foundation.Collections.IObservableVector<String> GridData{ get; };
Windows.Foundation.Collections.IObservableVector<String> FlowData{ get; };
}
}
Code language: C++ (cpp)
Изменение заголовочного файла (.h)
Удалите реализацию конструктора, оставьте только объявление.
Добавьте три закрытые переменные для хранения наборов данных.
Добавьте три открытых метода-геттера для обращения из XAML, например ListData().
#pragma once
#include "MainWindow.g.h"
namespace winrt::AppWinui::implementation
{
struct MainWindow : MainWindowT<MainWindow>
{
private:
winrt::Windows::Foundation::Collections::IObservableVector<hstring> m_listData;
winrt::Windows::Foundation::Collections::IObservableVector<hstring> m_gridData;
winrt::Windows::Foundation::Collections::IObservableVector<hstring> m_flowData;
public:
winrt::Windows::Foundation::Collections::IObservableVector<hstring> ListData();
winrt::Windows::Foundation::Collections::IObservableVector<hstring> GridData();
winrt::Windows::Foundation::Collections::IObservableVector<hstring> FlowData();
MainWindow();
int32_t MyProperty();
void MyProperty(int32_t value);
};
}
namespace winrt::AppWinui::factory_implementation
{
struct MainWindow : MainWindowT<MainWindow, implementation::MainWindow>
{
};
}
Code language: C++ (cpp)
Инициализация источников данных в файле .cpp
#include "pch.h"
#include "MainWindow.xaml.h"
#if __has_include("MainWindow.g.cpp")
#include "MainWindow.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::UI::Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace winrt::AppWinui::implementation
{
int32_t MainWindow::MyProperty()
{
throw hresult_not_implemented();
}
void MainWindow::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
MainWindow::MainWindow()
{
InitializeComponent();
m_listData = winrt::single_threaded_observable_vector<hstring>(
{ L"Alpha", L"Beta", L"Gamma" });
m_gridData = winrt::single_threaded_observable_vector<hstring>(
{ L"Плитка A", L"Плитка B", L"Плитка C", L"Плитка D" });
m_flowData = winrt::single_threaded_observable_vector<hstring>(
{ L"Потоковый элемент 1", L"Потоковый элемент 2", L"Потоковый элемент 3" });
}
winrt::Windows::Foundation::Collections::IObservableVector<hstring> MainWindow::ListData()
{
return m_listData;
}
winrt::Windows::Foundation::Collections::IObservableVector<hstring> MainWindow::GridData()
{
return m_gridData;
}
winrt::Windows::Foundation::Collections::IObservableVector<hstring> MainWindow::FlowData()
{
return m_flowData;
}
}
Code language: C++ (cpp)
В конструкторе инициализируем наблюдаемые векторы и присваиваем их закрытым полям, затем реализуем три открытые функции для возврата наборов данных.
Загрузка проекта
Элементы управления WinUI 3 C++ — Списки и коллекционные представления