もくじ
https://tera1707.com/entry/2022/02/06/144447
やりたいこと
Windowsの設定のホーム画面のように、
- 設定項目1つ分の枠について、
- 2列表示の時、
- ある程度の幅に収まっているときは、ウインドウの幅に合わせて設定項目の枠の幅が伸び縮みする
- ウインドウが一定の幅より大きくなると、設定項目の枠はそれ以上幅が大きくならない
- ウインドウが一定の幅より小さくなると、設定項目の枠はそれ以上幅が大きくならない
- さらにウインドウの幅が小さくなると、1列表示になる
- 1列表示の時、
- ある程度の幅に収まっているときは、ウインドウの幅に合わせて設定項目の枠の幅が伸び縮みする
- ウインドウが一定の幅より大きくなると、2列表示になる
- 2列表示の時、
という動きをさせたい。↓のようなイメージ。

※こういうのを「レスポンシブ」というのか?
前提
以下の環境で実験した。
作成したコード
動かすとこうなる

コード中身
<?xml version="1.0" encoding="utf-8"?> <Page x:Class="MyWinUI3PackageProjectTemplate6.View.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyWinUI3PackageProjectTemplate6.View" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid> <ItemsRepeater ItemsSource="{x:Bind MyDatas}" MaxWidth="800"> <ItemsRepeater.Layout> <!-- ItemsStretch を Fill にすると、ウインドウの幅までItemsRepeaterが広がってくれる --> <!-- そのうえで、ItemsRepeater自体のMaxWidthを、MinItemWidth の2倍より少し大きくしておくと、2列になったうえで各Itemの大きさが少しだけ大きくなってくれるような動きになる--> <UniformGridLayout MaximumRowsOrColumns="2" MinItemWidth="300" MinColumnSpacing="10" MinRowSpacing="10" ItemsStretch="Fill" ItemsJustification="Center"/> </ItemsRepeater.Layout> <DataTemplate x:DataType="local:MyData"> <Border BorderBrush="Red" BorderThickness="2" Margin="2" SizeChanged="Border_SizeChanged"> <Grid HorizontalAlignment="Stretch" Background="SkyBlue" Name="outer"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{x:Bind Data1}" HorizontalAlignment="Center"/> <ContentPresenter Grid.Row="2" Content="{x:Bind Toggle}" HorizontalAlignment="Center"/> </Grid> </Border> </DataTemplate> </ItemsRepeater> <!-- デバッグ用 --> <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Bottom" > <TextBlock x:Name="ItemSize" Foreground="Red"/> <Button Content="statusを進める" Click="Button_Click" /> </StackPanel> </Grid> </Page>
解説
ItemsRepeaterに適用したUniformGridLayoutのItemsStretchをFillにしておくと、
ウインドウの幅とItemsRepeaterの大きさが同じになってくれる。
(ウインドウを広げると、Itemの幅も広がってくれる)
UniformGridLayoutのMaximumRowsOrColumnsを2にしておくと、Itemの横並びが最大二個までになる。
ウインドウを縮めて、Itemの1こあたりの幅がMinItemWidthで指定した幅(今回の場合だと300)より小さくなると、2列だったItemが1列になる。
ItemsRepeater自体のMaxWidthを、MinItemWidthの2倍より少し大きくしておくと、2列になったうえで各Itemの大きさが少しだけ大きくなってくれるような動きになる。
※ItemsJustificationをいろいろ変えると、Itemの配置をいろいろ変えられる。
参考
XAML でのレスポンシブ レイアウト(直接実装方法には関係ないページ)
https://learn.microsoft.com/ja-jp/windows/apps/design/layout/layouts-with-xaml