読者です 読者をやめる 読者になる 読者になる

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

.Net系プログラムで勉強したこととか嵌ったことについて書いたりします。

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を活用すれば、イケている画面を作成する余地は十分にありそうです。