この記事は、XAML Advent Calendar 2017の22日目の記事です。
以前↓に書いた、各種グリッドレイアウトを補助するGridExtraというライブラリを更新しました。
WPF/UWP向けに、グリッドレイアウト補助ライブラリを作ってみました~GridExtra~ - SourceChord
Nugetから以下のコマンドでインストールできます。
Install-Package GridExtra
主に以下のような変更が入っています。
- GridExクラスの更新
- GridEx.AutoFillChildren添付プロパティ
- Gridパネル内の子要素を、UniformGridやWrapPanelみたいに各要素を自動で順々に並べる機能
- GridEx.AutoFillChildren添付プロパティ
- WrapPanelExクラスの追加
- WrapPanelEx.AdaptiveLayout添付プロパティ
- WrapPanelの子要素がOrientation方向の幅いっぱいに広がるようにレイアウトを自動調整する機能
- WrapPanelEx.AdaptiveLayout添付プロパティ
ということで変更点などを、ざっとご紹介したいと思います。
GridExの更新内容
GridEx.AutoFillChildren添付プロパティ
gridへの、要素の自動流し込み
今回の更新のメイン!! GridEx.AutoFillChildrenという添付プロパティをTrueにすると、子要素をGrid内の各領域へと自動で順番に流し込んでいきます。
Gridなんだけど、WrapPanelみたいに要素を順番に流し込んでいけるイメージ。
使い方
こういう風にグリッド内に順番にコントロールを配置したい場合、
以下のように、子要素でGrid.Row/Grid.Columnを個別に設定せず、自動で配置することができます。
<Grid ge:GridEx.ColumnDefinition="*, *"ge:GridEx.RowDefinition="Auto, Auto, Auto"ge:GridEx.AutoFillChildren="True"ShowGridLines="True"><TextBlock Text="Name:" /><TextBox VerticalAlignment="Top"Margin="5"/><TextBlock Text="Age:" /><TextBox VerticalAlignment="Top"Margin="5"/><Button ge:GridEx.Area="2, 1, 1, 1"Margin="5"Width="60"HorizontalAlignment="Right"Content="OK" /></Grid>
Orientationの指定
GridEx.AutoFillOrientation
添付プロパティを指定することで、自動レイアウトする方向を指定できます。
こんな風に、縦方向の並びで順番に並べることもできます。
<Grid ge:GridEx.ColumnDefinition="*, *, *"ge:GridEx.RowDefinition="*, *"ge:GridEx.AutoFillChildren="True"ge:GridEx.AutoFillOrientation="Vertical"><Button Content="1" /><Button Content="2" /><Button Content="3" /><Button Content="4" /><Button Content="5" /><Button Content="6" /></Grid>
自動レイアウトに、固定要素を混ぜる
AutoFillChildrenを用いたレイアウトをする際、GridEx.Area
やGridEx.AreaName
など、GridExでの位置指定を行う添付プロパティが設定された子要素があると、自動レイアウトの対象から除外し、指定された位置に固定配置します。
<Grid ge:GridEx.ColumnDefinition="*, *, *"ge:GridEx.RowDefinition="*, *"ge:GridEx.AutoFillChildren="True"><Button Content="1" /><Button Content="2" /><Button Content="3" /><Button Content="4" /><Button Content="Fixed Item"ge:GridEx.Area="0,1,1,1"/></Grid>
まぁ、これはこれでどこかで用途あるんじゃないかな、と。
AutoFill絡みのプロパティは、今後もう少し追加していきたいなと思います。
GridEx.Row/Column Definitionで、行・列サイズのmin/max指定に対応
GridExでは、GridEx.RowDefinition
、GridEx.ColumnDefinition
という添付プロパティで、Gridの行・列数を定義する機能を作ってました。
この定義では、行・列の各要素のサイズ指定はできたのですが、MinWidth/MinHeightなどの値を設定できませんでした。
行・列定義を行う文字列の文法に少し仕様を追加し、
以下のような形式で、複数の行や列のサイズをMin/Max条件含めてまとめて定義できるようにしました。
ge:GridEx.ColumnDefinition="50, *(50-200), 2*(80-), 2*(-300)"
こんな風にグリッド定義をすることができます。
<Grid ge:GridEx.RowDefinition="*, *, *, *"ge:GridEx.ColumnDefinition="50, *(50-200), 2*(80-), 2*(-300)"ShowGridLines="True"><Button Grid.Row="1"Grid.Column="2"Margin="5"Content="Button" /></Grid>
これは、以下のようなコードと同じレイアウトとなります。
<Grid.ColumnDefinitions><ColumnDefinition Width="50"/><ColumnDefinition Width="*"MinWidth="50"MaxWidth="200"/><ColumnDefinition Width="2*"MinWidth="80"/><ColumnDefinition Width="2*"MaxWidth="300"/></Grid.ColumnDefinitions>
地味ですが、これで一応GridExクラスの機能だけで、Gridの行・列 定義を一通りできるようになったかと思います。
WrapPanelExクラスの追加
WrapPanelのレイアウト調整を行うヘルパークラス、WrapPanelExを追加しました。
WrapPanelでWrapPanelEx.AdaptiveLayout="True"
という添付プロパティを設定すると、通常のWrapPanelのように各要素を等間隔で配置するのではなく、指定幅以上でパネルを埋め尽くすようにレイアウトします。
UWP Community ToolkitのAdaptiveGridViewのようなレイアウト方法です。
ちょっと言葉で表現しにくいので、動きは↓のgif見てください。
<Grid><Grid.RowDefinitions><RowDefinition /><RowDefinition Height="Auto"/></Grid.RowDefinitions><WrapPanel ItemWidth="200"ItemHeight="70"Orientation="Horizontal"ge:WrapPanelEx.AdaptiveLayout="{Binding IsChecked, ElementName=chkIsAdaptive}"><Button /><Button /><Button /><Button /><Button /><Button /><Button /></WrapPanel><CheckBox x:Name="chkIsAdaptive"Grid.Row="1"Margin="5"Content="WrapPanelEx.AdaptiveLayout"/></Grid>
今回の更新内容は以上ですが、今後も面白そうなレイアウト手法があれば、色々と取り入れながら更新していきたいと思ってます。