Dynamicly create a playboard for Minesweeper game
c#, mvvm, xaml
Solution
You can display your collection using an ItemsControl that has it's `ItemsPanel` set to a `Grid` or `UniformGrid`. I have some `ItemsControl` examples here that may help you, as I don't find MDSN's examples very helpful.
A `UniformGrid` would be easiest if you can bind your `Rows` and `Columns` properties to a property in your `ViewModel`, however that requires all your cells be the same size, and I can't remember if the properties `Rows` and `Columns` are DependencyProperties that participate in the binding system or not.
<ItemsControl ItemsSource="{Binding MyCollection}">
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding ColumnCount}"
Rows="{Binding RowCount}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
If this doesn't work for you, you can use a `Grid` as the `ItemsPanel` and set the `Grid.Row` and `Grid.Column` bindings in the `ItemContainerStyle`.
This will require you have properties on each of your cell objects in the `ObservableCollection` to say what Row/Column that cell is in, however I suspect you'll need these anyways to determine things like adjacent cells in your click command.
In addition, there's no built-in way to bind the number of Rows/Columns in your `Grid`, so I tend to use some custom attached properties that will dynamically build the Grid's `RowDefinitions` and `ColumnDefinitions` based on a bound value.
So your end result if you're using a Grid would probably look something like this:
<ItemsControl ItemsSource="{Binding Cells}">
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- This is assuming you use the attached properties linked above -->
<Grid local:GridHelpers.RowCount="{Binding Height}"
local:GridHelpers.ColumnCount="{Binding Width}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column"
Value="{Binding ColumnIndex}" />
<Setter Property="Grid.Row"
Value="{Binding RowIndex}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
With a Model/ViewModel looking something like this
public class GameViewModel
{
// These should be full properties w/ property change notification
// but leaving that out for simplicity right now
public int Height;
public int Width;
public ObservableCollection<CellModel> Cells;
}
public class CellModel
{
// Same thing, full properties w/ property change notification
public int ColumnIndex;
public int RowIndex;
public bool IsVisible;
public bool IsMine;
public int NumberAdjacentMines;
}
Problem
with the objective to learn C#, XAML and especially MVVM I started to program the Minesweeper game. First version I made was without the MVVM part, where I created and added the buttons with C# code instead of doing it in XAML via the MVVM way. Now I try to apply the MVVM pattern into the game. I made an own User Control which contains a button representing a minefield part. This control also has a ViewModel and a Model Class to store some state data and handle some commands. In a test project I create 4 of those own User Controls and try to put them in a grid where the buttons forms a square of 2 by 2 buttons. In the code behind, the buttons are put in an ObservableCollection object. I assume that in this object the buttons are listed and indexed like: ``` Button1 Button2 Button3 Button4 ``` but in the presentation grid I want the buttons to be shown like ``` Button1 | Button2 --------+-------- Button3 | Button4 ``` The question is: how do I do that dynamicly? Cause in my test project I test with 4 buttons, but In the project I want to use this, the amount of buttons can be different depending on the difficulty of the game the player has chosen. And a second question is how I can figure out what the neigbhours are of a button. So if the grid is 4 by 5 containing 20 buttons. And for example I pick button 8 which has as neighbour buttons number 2, 3, 4, 7, 9, 12, 13 and 14. How can I reach those neighbour buttons when the buttons are listed? I hope my questions are clear enough. Thank you in advance!