はまったりひらめいたり…とか…

Angularや.NETやAzureやその他色々。

Xamarin.FormsのGridについて

下図の画面をGridで作成するための前準備のお話し。

Gridの仕様(?)が結構特殊な感じだったためφ(..)
f:id:TakasDev:20160518000634p:plain


Xamarin.FormsのAngerの内容を流用しているため、Xamlの話ではありません。

www.syntaxismyui.com


AngerのCardsの画面の作り方、結構好きなんですが

これ、Xamlで作るにはどうしたらいいんですかね?さっぱり想像つきません…

Grid

Grid grid = new Grid
{
    RowSpacing = 1,
    ColumnSpacing = 1,
    BackgroundColor = UserPageStyleKit.CardBorderColor,
    VerticalOptions = LayoutOptions.FillAndExpand,
    RowDefinitions =
    {
        new RowDefinition { Height = new GridLength(80, GridUnitType.Absolute)},
        new RowDefinition { Height = new GridLength(50, GridUnitType.Absolute)}
    },
    ColumnDefinitions =
    {
        new ColumnDefinition { Width = new GridLength(100, GridUnitType.Absolute)},
        new ColumnDefinition { Width = new GridLength ( 1,GridUnitType.Star)},
        new ColumnDefinition { Width = new GridLength ( 10,GridUnitType.Absolute)},
        new ColumnDefinition { Width = new GridLength ( 140,GridUnitType.Absolute)}
    }
};

上記で2行4列のGridとなります。

下図の様なGridの配置となります。

f:id:TakasDev:20160518001048p:plain

それぞれGridLengthが指定されていますが、紫色背景の列は

GridUnitType.starが指定されているため、表示領域により動的に幅が変わるようです。

例えば、下記のようにソースを変更すると、1:2で描画されるようです。

ColumnDefinitions =
{
    new ColumnDefinition { Width = new GridLength(100, GridUnitType.Absolute)},
    new ColumnDefinition { Width = new GridLength ( 1,GridUnitType.Star)},
    new ColumnDefinition { Width = new GridLength ( 2,GridUnitType.Star)},
    new ColumnDefinition { Width = new GridLength ( 140,GridUnitType.Absolute)}
}

f:id:TakasDev:20160518001228p:plain

Grid要素の配置

Gridに対する要素の配置は、下記のようなソースで行っています。

grid.Children.Add(new Label { Text = "(0,1,0,1)", BackgroundColor = Color.Black }, 0, 1, 0, 1);
grid.Children.Add(new Label { Text = "(1,2,0,1)", BackgroundColor = Color.White }, 1, 2, 0, 1);
grid.Children.Add(new Label { Text = "(2,3,0,1)", BackgroundColor = Color.Blue }, 2, 3, 0, 1);
grid.Children.Add(new Label { Text = "(3,4,0,1)", BackgroundColor = Color.Pink }, 3, 4, 0, 1);
grid.Children.Add(new Label { Text = "(0,1,1,2)", BackgroundColor = Color.Silver }, 0, 1, 1, 2);
grid.Children.Add(new Label { Text = "(1,2,1,2)", BackgroundColor = Color.Purple }, 1, 2, 1, 2);

Text要素が、上図の(x,x,x,x)で表記されている内容です。

下図のような感じの考えたでしょうか?(手書き汚くてすみません)

f:id:TakasDev:20160518001432p:plain

なので、(0,1,0,2)と指定してやることで

下図のようにRowをまたがった描画も可能となります。

f:id:TakasDev:20160518001456p:plain

ただし、下記のように描画箇所がバッティングを起こすと

後に宣言されたものが優先して描画されます。

grid.Children.Add(new Label { Text = "(0,1,0,2)", BackgroundColor = Color.Black }, 0, 1, 0, 2);
grid.Children.Add(new Label { Text = "(0,1,1,2)", BackgroundColor = Color.Silver }, 0, 1, 1, 2);

f:id:TakasDev:20160518001551p:plain

Column数以上の数値を指定したとき

ここ、少し戸惑いました。

基本形を下図とします。

f:id:TakasDev:20160518001712p:plain

grid.Children.Add(new Label { Text = "(3,5,0,2)", BackgroundColor = Color.Blue }, 3, 5, 0, 2);

上記コードを突っ込んだときエラーになるかというとなりませんでした。

下図のようになります。

見にくいですが、2/3列目が縮小されています。
f:id:TakasDev:20160518001805p:plain

2/3列目をAbsolute属性に変更し、同様のソースで実行したところ

下図のようになりました。
f:id:TakasDev:20160518002002p:plain

領域をフルに活用して描画するようになっているのでしょうか?

Column数が拡張されているように見受けられます。

ちなみに、下のようなソースで実行した場合

grid.Children.Add(new Label { Text = "(4,100,0,1)", BackgroundColor = Color.Maroon }, 4, 100, 0, 1);
grid.Children.Add(new Label { Text = "(4,20,1,2)", BackgroundColor = Color.Maroon }, 4, 20, 1, 2);

下図のような描画となります。
f:id:TakasDev:20160518002250p:plain

残領域で100カラム作っているんですかね?

Gridのここらへんの動作分かってないと

ほぼエラーが発生しないんでドツボにはまることになるかもしれません。

まとめ

気を付けなければいけない部分はありますが

Gridを活用すれば、イケている画面を作成する余地は十分にありそうです。