带有ItemsControl和Grid的WPF动态布局

Jas*_*ams 35 wpf grid dynamic itemscontrol wpf-controls

我正在创建一个WPF表单.其中一个要求是它具有基于扇区的布局,以便可以将控件明确地放置在扇区/单元之一中.

我在下面创建了一个tic-tac-toe示例来表达我的问题:

有两种类型和一种基本类型:

public class XMoveViewModel : MoveViewModel
{
}
public class OMoveViewModel : MoveViewModel
{
}
public class MoveViewModel
{
    public int Row { get; set; }
    public int Column { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

表单的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,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>
Run Code Online (Sandbox Code Playgroud)

当我开始时对我来说不那么明显的是ItemsControl元素实际上将每个项目包装在一个容器中,因此我的Grid.Row和Grid.Column绑定被忽略,因为图像不直接包含在网格中.因此,所有图像都放在默认的行和列(0,0)中.

怎么了:

发生了什么http://i48.tinypic.com/29xyl9j.png

期望的结果:

期望的结果http://i50.tinypic.com/2druhqd.png

所以,我的问题是:如何在网格中实现控件的动态放置?我更喜欢XAML/Data Binding/MVVM友好的解决方案.

谢谢.

我在这里输入了最终代码:http: //www.centrolutions.com/downloads/TicTacToe.zip

Cha*_*lie 28

你走在正确的轨道上.您只需创建一个Style并将其应用于ItemsControl.ItemContainerStyle.然后,在样式中,为Grid.Row和指定一个setter Grid.Column.在ItemContainerStyle将得到应用到各个项目生成的容器.