下面要介绍的是一些用来显示多个项目的视图,经常用来呈现多条数据,显示一个列表,或者显示一个网格或者表格的布局。
| 控件 | 介绍 |
|---|---|
| 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="Item One" 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="Item Two" 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="Item Three" 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="Tile 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="Tile 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="Tile 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="Tile 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 Panel" 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来绑定数据源,数据来后台构建,例如 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中修改
构造函数去掉实现部分,只保留声明
增加三个私有属性,用来存储数据
增加三个方法,用来提供外面调用,如: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"Tile A", L"Tile B", L"Tile C", L"Tile D" });
m_flowData = winrt::single_threaded_observable_vector<hstring>(
{ L"Flow Item 1", L"Flow Item 2", L"Flow Item 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)
在构造函数中,初始化数据源,给私有变量赋值,然后实现三个public函数,用来返回。
项目下载
Previous: WinUI 3 C++ 控件篇-ListBox的Items动态添加
Next: WinUI 3 C++ 控件篇-滑块、进度条控件