ItemsControl + UniformGrid:在每个单元格中显示自定义类

时间:2017-02-21 16:09:51

标签: wpf data-binding itemscontrol

我试图在统一网格的单独单元格中显示Block的每个GameBoard.BlockList(我的自定义类以及更多属性)。

这样就会显示一个Common.XY.Block字符串,据我所知。阻止不是UIElement

<ItemsControl Grid.Row="1" Grid.Column="1" ItemsSource="{Binding GameBoard.BlockList}">
      <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
              <UniformGrid Background="Transparent" Rows="{Binding GameBoard.Rows}" Columns="{Binding GameBoard.Columns}" Margin="1,1,1,1"/>                   
          </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>            
</ItemsControl>

所以我想我可以用DataTemplate这样的东西:

<ItemsControl.ItemTemplate>
  <DataTemplate>
    <Border BorderThickness="1" BorderBrush="Black">
      <Rectangle Fill="Transparent" Drop="Rectangle_Drop" AllowDrop="True" Width="50" Height="50"/>                  
     </Border>
   </DataTemplate>
</ItemsControl.ItemTemplate>

这将在UniformGrid Rectangle的每个单元格中添加Border,但我无法访问自定义区块。

我不知道如何在这里实现我的目标。我想使用GameBoard作为&#34;主要来源&#34;我存储数据并使用它的地方。

如何使用UniformGrid将{flxiblity与ItemsControl一方保持一致,并使用另一方GameBoard的所有数据?

1 个答案:

答案 0 :(得分:1)

此示例可以显示正确的路径。您应该在其中设置ItemContainerStyle和Bind Grid.Row和Grid.Column属性。您应该使用ItemTemplate将每个块的属性用于一个或模式UIElements。

  <ItemsControl Grid.Row="1" Grid.Column="1" DataContext="{Binding GameBoard}" ItemsSource="{Binding BlockList}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Background="Transparent" 
                             Rows="{Binding GameBoard.Rows}" 
                             Columns="{Binding GameBoard.Columns}" Margin="1,1,1,1"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Grid.Row" Value="{Binding Row}"/>
                <Setter Property="Grid.Column" Value="{Binding Column}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border BorderThickness="1" BorderBrush="Black">
                    <Grid>
                        <Rectangle Fill="{Binding Background}" />
                        <TextBlock Text="{Binding Name}"/>
                    </Grid>
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

ViewModel是你的GameBoard。它应该具有统一网格的总行数和列数,以及一个用块填充的ObservableCollection:

public class GameBoard : INotifyPropertyChanged
{
    public GameBoard()
    {
        var m1 = new Block() { Name = "b1", Background = Brushes.Red, Col=0, Row = 0 };
        var m2 = new Block() { Name = "b2", Background = Brushes.Gray, Col=0, Row = 0 };
        var m3 = new Block() { Name = "b3", Background = Brushes.Goldenrod, Col=0, Row = 0 };
        var m4 = new Block() { Name = "b4", Background = Brushes.Honeydew, Col=0, Row = 0 };

        _blockList = new ObservableCollection<Block>() { m1, m2, m3, m4 }; 
    }

    int _rows = 2;
    public int Rows { get { return _rows; } set { _rows = value; RaisePropertyChanged("Rows"); } }

    int _cols = 2;
    public int Columns { get { return _cols; } set { _cols = value; RaisePropertyChanged("Columns"); } }

    ObservableCollection<Block> _blockList;
    public ObservableCollection<Block> BlockList { get { return _blockList; } set { _blockList = value; RaisePropertyChanged("BlockList"); } }

    public event PropertyChangedEventHandler PropertyChanged;
    void RaisePropertyChanged(string propname)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
    }
}

您的模型应该有关于碎片的不同信息,例如它们的名称,颜色,位置(行和列)等。

public class Block : INotifyPropertyChanged
{

    int _row;
    public int Row { get { return _row; } set { _row = value; RaisePropertyChanged("Row"); } }

    int _col;
    public int Col { get { return _col; } set { _col = value; RaisePropertyChanged("Col"); } }

    string _name;
    public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } }

    Brush _background;
    public Brush Background { get { return _background; } set { _background = value; RaisePropertyChanged("Background"); } }

    public event PropertyChangedEventHandler PropertyChanged;
    void RaisePropertyChanged(string propname)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
    }


}

最后,您应该正确设置DataContext:

    public MainWindow()
    {
        GameBoard = new GameBoard(); 
        InitializeComponent();
        DataContext = this;
    }
    public GameBoard GameBoard { get; set; }