接下來要介紹數種用來顯示多筆項目的檢視控制項,常被用來呈現多組資料,實作垂直清單、網格卡片或是表格版面。
| 控制項 | 說明 |
|---|---|
| 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="項目一" 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="項目二" 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="項目三" 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++ 控制項手冊 — 清單與集合檢視