views:

60

answers:

3

I need to keep checkboxes in a collection and access them via matrix coordinates.

The following example works but only if I know the size of the matrix beforehand, since an array is used.

What would be the best kind of approach/collection to achieve the same result but also allow the matrix to be defined at runtime, e.g. Dictionary<>, Tuple<>, KeyValuePair<>?

alt text

using System;
using System.Windows;
using System.Windows.Controls;

namespace TestDoubarray
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            CheckBox[,] checkBoxes = new CheckBox[10, 10];

            for (int x = 0; x < 10; x++)
            {
                for (int y = 0; y < 10; y++)
                {
                    CheckBox cb = new CheckBox();
                    cb.Tag = String.Format("x={0}/y={1}", x, y);
                    checkBoxes[x,y] = cb;
                }
            }

            CheckBox cbOut = checkBoxes[4, 8];
            Message.Text = cbOut.Tag.ToString();
        }
    }
}
+2  A: 

You can create a struct that holds the coordinates as key and use it in a dictionary.

struct CheckBoxCoord{
 public int X{get;set;}
 public int Y{get;set;}
}


Dictionary<CheckBoxCoord,CheckBox> m_map=new Dictionary<CheckBoxCoord,CheckBox>();

Look also here if to see how to find them directly.

HCL
using a struct as a dictionary key is a useful pattern, thanks
Edward Tanguay
A: 

A dictionary is very much the class intended for this sort of situation, and would be my choice.

In general I'd avoid Tuples, even for use as the index. (I've always felt that any time you can use a tuple, you should use a struct. HCL's example could use a 2-tuple instead of a struct as the key... but then you lose the ability to name the X and Y co-ords, to no gain.)

KeyValuePair is most useful when you already have a dictionary, and want to enumerate it, or otherwise deal with the dictionary elements as a pair.

Tynam
+1  A: 

You can still use an array even if you don't know it's dimensions until runtime by using its GetUpperBound method to find the size for example;

int x_len = 13; // x_len and y_len can be any size >= 0
int y_len = 11;

CheckBox[,] checkBoxes = new CheckBox[x_len, y_len];

for (int x = 0; x <= checkBoxes.GetUpperBound(0); x++)
{
    for (int y = 0; y <= checkBoxes.GetUpperBound(1); y++)
    {
        CheckBox cb = new CheckBox();
        cb.Tag = String.Format("x={0}/y={1}", x, y);
        checkBoxes[x, y] = cb;
    }
}

CheckBox cbOut = checkBoxes[4, 8];
YouMustLeaveNow