Reputation: 474
I'm trying to display every Block
(my custom class with some more properties) of the GameBoard.BlockList
in a seperate cell of the uniform grid.
This way there will be just a Common.XY.Block
string be displayed, which I understand. Block is not an 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>
So I thought I could use as a DataTemplate
soemthing like this:
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Black">
<Rectangle Fill="Transparent" Drop="Rectangle_Drop" AllowDrop="True" Width="50" Height="50"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
This will add in each cell of the UniformGrid
a Rectangle
, surrounded by a Border
, but I don't have access to my custom block.
I don't know exactly how to achieve my goal here. I want to use the GameBoard
as the "main source" where I store data and work with it.
How do I have to use the UniformGrid
to keep its felxiblity with the ItemsControl
one the one side and use all data of the GameBoard
on the other side?
Upvotes: 0
Views: 8003
Reputation: 3631
This example can show you the correct path. You should set ItemContainerStyle
and Bind Grid.Row and Grid.Column properties of the Blocks in it. You should use ItemTemplate
to use the properties of each Block into one or mode 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>
The ViewModel is your GameBoard. It should have number of Total rows and columns of the Uniform Grid and also an ObservableCollection, filled with the Blocks:
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));
}
}
Your Model should have different information about the pieces, for example their name, Color, Position (Row and Column) and etc.
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));
}
}
and at last, you should set the DataContext properly:
public MainWindow()
{
GameBoard = new GameBoard();
InitializeComponent();
DataContext = this;
}
public GameBoard GameBoard { get; set; }
Upvotes: 3