web-dev-qa-db-ja.com

ItemsControlとグリッドを使用したWPF動的レイアウト

WPFフォームを作成しています。要件の1つは、コントロールをセクター/セルの1つに明示的に配置できるように、セクターベースのレイアウトを使用することです。

私の問題を伝えるために、以下に三目並べの例を作成しました。

2つのタイプと1つの基本タイプがあります。

public class XMoveViewModel : MoveViewModel
{
}
public class OMoveViewModel : MoveViewModel
{
}
public class MoveViewModel
{
    public int Row { get; set; }
    public int Column { get; set; }
}

フォームのDataContextは、次のインスタンスに設定されます。

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        Moves = new ObservableCollection<MoveViewModel>()
        {
            new XMoveViewModel() { Row = 0, Column = 0 },
            new OMoveViewModel() { Row = 1, Column = 0 },
            new XMoveViewModel() { Row = 1, Column = 1 },
            new OMoveViewModel() { Row = 0, Column = 2 },
            new XMoveViewModel() { Row = 2, Column = 2}
        };
    }
    public ObservableCollection<MoveViewModel> Moves
    {
        get;
        set;
    }
}

そして最後に、XAMLは次のようになります。

 <Window.Resources>
    <DataTemplate DataType="{x:Type vm:XMoveViewModel}">
        <Image Source="XMove.png" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Column}" Stretch="None" />
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:OMoveViewModel}">
        <Image Source="OMove.png" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Column}" Stretch="None" />
    </DataTemplate>
</Window.Resources>
<Grid>
    <ItemsControl ItemsSource="{Binding Path=Moves}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid ShowGridLines="True">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>

私が始めたとき、ItemsControl要素が実際に各アイテムをコンテナにラップしていることは私にはそれほど明白ではありませんでした。そのため、画像がグリッド内に直接含まれていないため、Grid.RowとGrid.Columnのバインディングは無視されます。したがって、すべての画像はデフォルトの行と列(0、0)に配置されます。

何が起こっている:

What is happening

望ましい結果:

The desired result

だから、私の質問はこれです:グリッド内のコントロールの動的な配置をどのように達成できますか? XAML /データバインディング/ MVVMに適したソリューションをお勧めします。

ありがとう。

私はここに最終的なコードを置きました: http://www.centrolutions.com/downloads/TicTacToe.Zip

35
Jason Williams

あなたは正しい方向に進んでいます。 Styleを作成し、それをItemsControl.ItemContainerStyleに適用するだけです。次に、スタイルで、Grid.RowGrid.Columnのセッターを指定します。 ItemContainerStyleは、アイテムごとに生成されたコンテナーに適用されます。

28
Charlie