2010-05-26 158 views
32

我正在创建一个WPF表单。其中一个要求是它具有基于扇区的布局,以便可以将控制明确地放置在其中一个扇区/单元中。带ItemsControl和Grid的WPF动态布局

我已经创建了一个井字棋例如低于传达我的问题:

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

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 http://i48.tinypic.com/29xyl9j.png

期望的结果:

The desired result http://i50.tinypic.com/2druhqd.png

所以,我的问题是:我怎么能实现在网格中我控制的动态布局?我更喜欢XAML /数据绑定/ MVVM友好的解决方案。

谢谢。

我已经把这里的最终代码: http://www.centrolutions.com/downloads/TicTacToe.zip

+0

嘿杰森, 任何机会得到你的井字游戏的完整代码?我很想看看。 谢谢! – VitalyB 2010-09-01 19:05:10

+2

不幸的是,这个项目只是一个例子,而不是一个完整的游戏。这是一个更大的(非tic-tac-toe)项目的原型。如果您仍然对此感兴趣,我已经在最初的问题下面提供了最终代码的链接。 – 2010-09-02 13:37:35

+0

我来看看。谢谢! – VitalyB 2010-09-02 21:58:20

回答

25

你在正确的轨道上。您只需创建一个Style并将其应用于ItemsControl.ItemContainerStyle。然后,在该样式中,为Grid.RowGrid.Column指定一个设置器。 ItemContainerStyle将应用于为每个项目生成的容器。

+0

啊哈!我知道我错过了一些东西。感谢您的帮助。这很好。 – 2010-05-26 17:25:10

+1

我想在Silverlight中做同样的事情,有没有人知道一种方法来做到这一点? (ItemContainerStyle在Silverlight中不可用...) – 2010-11-12 11:07:54