0

For the purpose of learning MVVM and WPF (I am fairly new to both these), I am building a simple game.

The game board consists of 9 (3x3) tiles (I want to have it NxN later on, but 3x3 is good enough for the example), which need to be evenly placed next to each other in three rows. I have defined an user control for the tiles as shown below in the View XAML.

The problem: while my data bindings work fine, I have been unable to find a layout where I could place my UserControls, as I cannot use ItemsSource and ItemTemplate with a Grid or a Canvas.

Since the game tiles might change their (PositionX and PositionY), I am looking for a layout that could support placement of user controls in X and Y coordinates, something like Grid.Column and Grid.Row (or Canvas.Left and .Top properties).

P.S. Never mind the ListBox, it is there just to make sure the data bindings worked and the tile value was displayed on the tiles.

View XAML:

    <UserControl.Resources>
        <DataTemplate x:Key="TileTemplate">
            <Border x:Name="GamePieceItem" BorderThickness="2" BorderBrush="DimGray"
                    CornerRadius="5" Background="LightYellow" Height="60" Width="60"
                    Grid.Column="{Binding Path=PositionX, Mode=TwoWay}"
                    Grid.Row="{Binding Path=PositionY, Mode=TwoWay}">
                <TextBlock Text="{Binding Path=TileValue, Mode=TwoWay}" FontSize="40" FontWeight="Bold"
                       HorizontalAlignment="Center" VerticalAlignment="Center"
                       x:Name="ValueField"
                       Margin="2"
                       />
            </Border>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
    <ListBox ItemsSource="{Binding GameTiles}"
              ItemTemplate="{StaticResource TileTemplate}"/>
    </Grid>
</UserControl>

Model:

    public class GameTile : INotifyPropertyChanged
    {
        private int _positionx;
        private int _positiony;
        private int _tilevalue;

        public int PositionX
        {
            get { return _positionx; }
            set
            {
                    _positionx = value;
                    RaisePropertyChanged("PositionX");
            }
        }

        public int PositionY
        {
            get { return _positiony; }

            set
            {
                    _positiony = value;
                    RaisePropertyChanged("PositionY");
            }
        }

        public int TileValue
        {
            get
            { return _tilevalue; }
            set
            {
                _tilevalue = value;
                RaisePropertyChanged("TileValue");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }

        }
    }

}

ViewModel:

    public class GameTileViewModel
    {
        public ObservableCollection<GameTile> GameTiles
        {
            get;
            set;
        }

        public void CreateBoard()
        {
            ObservableCollection<GameTile> gametiles = new ObservableCollection<GameTile>();
            // the game board should be auto-generated in a loop, these are just two examples of the tiles
            gametiles.Add(new GameTile { SequencePosition = 0, PositionX = 0, PositionY = 0, TileValue = 3 });
            gametiles.Add(new GameTile { SequencePosition = 1, PositionX = 1, PositionY = 1, TileValue = 5 });
            GameTiles = gametiles;
        }
    }

MainWindow XAML:

    <Grid>
        <views:GameBoardView x:Name="GameBoard" Loaded="GameBoard_Loaded"/>
    </Grid>

MainWindow code behind:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void GameBoard_Loaded(object sender, RoutedEventArgs e)
        {
            GameTileViewModel GameBoardObject = new GameTileViewModel();
            GameBoardObject.CreateBoard();
            GameBoard.DataContext = GameBoardObject;

        }
    }
Raits
  • 85
  • 9
  • I thought it would be appropriate, as well. Yet XAML gives me an error 'The property 'ItemsSource' was not found in type 'Grid'`. Perhaps there is some advanced way how to get the usercontrols there, but this is exactly what I cannot figure out. – Raits Jan 11 '22 at 22:15
  • See the duplicate questions and answers. – Clemens Jan 11 '22 at 23:13

0 Answers0