0

I am currently trying to create a little Battleship application using WPF. Some people were advertising the MVVM pattern for this, so I gave it a try (I have no experience with WPF or Forms). Everything seems to be working out quite well after some initial issues, but right now I hit a wall which I don't know how to break through:

As you can imagine, there is a Battleship "grid" (not to confuse with the WPF grid, although I just got an idea of what I could use instead perhaps... let me think about this, but the answer to the following question still interests me) which I'd like to draw on a Canvas. I succeeded without MVVM before, but I just don't know how to do it with MVVM. The drawn "grid" on the Canvas should consist of something that is always drawn, namely 11 horizontal and 11 vertical lines, and the ships (which could consist of any shape sitting in one of the squares defined by the crossing lines). The code for my BSGrid:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Battleship.Entities
{
  public class BSGrid
  {
    public const int Size = 10;

    // TileState is an enum consisting of Unchecked, Checked, ShipPart,...
    private TileState[,] sea = new TileState[Size, Size];

    public TileState this[BSPoint pos]
    {
      get { return sea[pos.x, pos.y]; }
      set { sea[pos.x, pos.y] = value; }
    }

    public TileState this[int x, int y]
    {
      get { return sea[x, y]; }
      set { sea[x, y] = value; }
    }

    public BSGrid()
    {
    }
  }
}

Do you have any proposal as of how to bind the canvas "content" to the data of a BSGrid? When I was drawing it before, I just went through the array and drew, say, a rectangle if there was a ship part on the tile or such. I could surely extract some of the data of a grid into, say, a List of Rects to be drawn then, but I don't know if this would be "good" and still wouldn't know how to draw from within the ViewModel at all. I'll be glad for any suggestions :-)

InvisiblePanda
  • 1,589
  • 2
  • 16
  • 39
  • 1
    You might model your ships as rectangles on a Canvas that is the `ItemsPanel` of an ItemsControl, like shown in [this answer](http://stackoverflow.com/a/22325266/1136211). – Clemens Mar 31 '14 at 11:36
  • @Clemens I think I even found that one before when looking for a solution on here, but I discarded it for some reason. While I switched to doing my game without MVVM for now, the answer still interests me (as I wrote above), and I think that your other answer can be generalized so I can use it. Thanks! – InvisiblePanda Mar 31 '14 at 14:11
  • In order to use grid cell indices instead of absolute coordinates, you may replace the Canvas by a Grid and set the `Grid.Column`, `Grid.Row`, `Grid.ColumnSpan` and `Grid.RowSpan` properties by the ItemStyle and ItemTemplate. – Clemens Mar 31 '14 at 16:21

1 Answers1

0

I got this to work by creating my own class

public class BattleshipCanvas : Canvas
{
  // ...
}

with a DependencyProperty for the BSGrid, as is kind of 'standard practice' in WPF but I didn't know at that time.

InvisiblePanda
  • 1,589
  • 2
  • 16
  • 39