泥庭

2013年5月29日

Gridへのアイテムのバインド(WPF編)

Filed under: .NET, WPF — タグ: — yone64 @ 11:55 PM

めっちゃ久しぶりにWPFのお話、

Gridは、コントロールをマス目で並べるときにとっても便利なコントロールです。たとえば、以下のようなレイアウトは、Gridが得意とするものの一つです。

image

この場合の、XAMLは以下の通りです。簡潔でよいのですが、子要素がXAML上に固定されているのは扱いづらいので、駒情報のコレクションをBindingすることで、XAMLから分離したいところです。

<Window x:Class="WPFBindSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="525" Width="525">
    <Grid ShowGridLines="True" Background="LightGreen">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Ellipse Grid.Column="4" Grid.Row="4" Margin="5" Fill="White"/>
        <Ellipse Grid.Column="3" Grid.Row="3" Margin="5" Fill="White"/>
        <Ellipse Grid.Column="3" Grid.Row="4" Margin="5" Fill="Black"/>
        <Ellipse Grid.Column="4" Grid.Row="3" Margin="5" Fill="Black"/>
    </Grid>
</Window>

しかし、GridはItemsControlのサブクラスではないため、ItemsSouceプロパティーは存在せず、したがってCollectionとのBindingもできません。残念! こういう場合はどうするかというと、ItemsControlを利用しCollectionとのBindingをしつつ、ItemPanelでGridを指定することになります。XAMLは以下の通り。

<Window x:Class="WPFBindSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFBindSample"
        Title="MainWindow" Height="525" Width="525">

    <Window.Resources>
        <local:ColorToSolidColorBrushValueConverter  x:Key="ColorBrushConverter"/>
    </Window.Resources>
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid Background="LightGreen" ShowGridLines="True">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                    </Grid.RowDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Grid.Column" Value="{Binding Path=ColumnIndex}"/>
                <Setter Property="Grid.Row" Value="{Binding Path=RowIndex}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Ellipse  Margin="5"
                    Fill="{Binding Path=Color,
                    Converter={StaticResource ResourceKey=ColorBrushConverter}}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

ポイントは、ItemContainerStyleでStyleを利用しGrid.ColunとGridRowに対してBindingを設定しているところ。これにより、Grid上の位置をBidingで設定することが可能になります。このXAMLに対して、コードビハインドで、以下のようなDataを設定してあげると、当初と同じ画面が表示されます。

this.DataContext = new[]
{
    new {Color = Colors.White, ColumnIndex = 3, RowIndex = 3},
    new {Color = Colors.White, ColumnIndex = 4, RowIndex = 4},
    new {Color = Colors.Black, ColumnIndex = 3, RowIndex = 4},
    new {Color = Colors.Black, ColumnIndex = 4, RowIndex = 3},
};

WPFだとこんな感じでできますが、Storeアプリだとこの方法はうまくいきません。詳しくは次回。

コメントする »

まだコメントはありません。

RSS feed for comments on this post. TrackBack URI

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

WordPress.com Blog.

%d人のブロガーが「いいね」をつけました。