shuhelohelo’s blog

Xamarin.Forms多めです.

Xamarin.FormsのBindableLayoutについて

Layoutに表示する項目(アイテム)のUIを統一したい場合に使います.

Using Bindable Layouts with Xamarin.Forms Controls | Syncfusion Blogs

ListViewでListItemに対してUIのテンプレートを適用して,全てのItemを同じ見た目にする,というのはよくやります.

ListViewを始めとしたコレクション系のコントロールでは当たり前のように行いますが,Grid,StackLayout,FlexLayoutなどのLayoutに対しては,BindableLayoutを使います.

これらのLayout系のコントロール内に配置するコントロールのUIを統一したいことがあると思います.

StackLayoutは特にその機会が多いのではないかなと思います.

StackLayoutにコレクションを統一されたUIで表示したい場合,以下のようにします.

XAML

    <StackLayout BindableLayout.ItemsSource="{Binding Data}">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <Label
                    Margin="25"
                    BackgroundColor="{Binding Color}"
                    FontAttributes="Italic"
                    FontSize="20"
                    HeightRequest="105"
                    HorizontalTextAlignment="Center"
                    Text="{Binding Text}"
                    VerticalTextAlignment="Center" />
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </StackLayout>

以下のようなコレクションがあったときに,それをStackLayoutのItemsSourceにバインドします.

        public ObservableCollection<Model> Data { get; set; } = new ObservableCollection<Model>
        {
            new Model{Text="Pink",Color=Color.DeepPink},
            new Model{Text="Crimson",Color=Color.Crimson},
            new Model{Text="Aqua",Color=Color.Aqua},
            new Model{Text="Blue",Color=Color.Blue},
        };

すると,以下のように表示されます.

f:id:shuhelohelo:20200224204703p:plain

これをGridでやると,以下のようになります.

Gridで使うために,RowとColumnという2つのプロパティをModelクラスに追加しています.

    <Grid BindableLayout.ItemsSource="{Binding Data}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <Label
                    Grid.Row="{Binding Row}"
                    Grid.Column="{Binding Column}"
                    Margin="25"
                    BackgroundColor="{Binding Color}"
                    FontAttributes="Italic"
                    FontSize="20"
                    HeightRequest="105"
                    HorizontalTextAlignment="Center"
                    Text="{Binding Text}"
                    VerticalTextAlignment="Center" />
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </Grid>
        public ObservableCollection<Model> Data { get; set; } = new ObservableCollection<Model>
        {
            new Model{Text="Pink",Color=Color.DeepPink,Row=0,Column=0},
            new Model{Text="Crimson",Color=Color.Crimson,Row=0,Column=1},
            new Model{Text="Aqua",Color=Color.Aqua,Row=1,Column=0},
            new Model{Text="Blue",Color=Color.Blue,Row=1,Column=1},
        };

表示は以下のようになります. f:id:shuhelohelo:20200224205530p:plain