Reputation: 283
Is there a standard pattern for identifying the parent object of a child object in a composite object, when you can't set data in the child object at creation?
I'm making a chess-like board. The board is composed of a grid of picture boxes. To model the board I keep an array of "uxSquares", which contain the picture box plus some other data I'll need. Something akin to:
private class uxSquare
{
public int RowIndex { get; private set; }
public int ColumnIndex { get; private set; }
// ... other stuff
public uxSquare(int RowIndex, int ColumnIndex)
{
this.RowIndex = RowIndex;
this.ColumnIndex = ColumnIndex;
this.PictureBox = new PictureBox();
this.PictureBox.Name = "R" + RowIndex.ToString() +
"C" + ColumnIndex.ToString();
}
}
During form load I create a 2 dimensional (row, col) array of uxSquares, and place the picture box from each uxSquare on the form in a grid layout. With the creation of each Picture Box, I'm storing the uxSquares[,] indices in the name of the PictureBox (seen in the uxSquare constructor above).
for (int rowIndex = 0; rowIndex < countOfRows; rowIndex++)
{
for (int colIndex = 0; colIndex < countOfColumns; colIndex++)
{
// create the uxSquare array
uxSquares[rowIndex, colIndex] = new uxSquare(rowIndex, colIndex);
// ... place pictureBox in gridlayout, plus more stuff
}
}
When the user clicks on a Picture Box, I need to know which uxSquare in the array owns that picture box control. Currently, in the shared click handler for the Picture Boxes, I'm parsing the name of the Sender object to get the uxSquares indices.
This seems like a gross hack, keeping array indices in the name of the control. However, my alternative appears to be keeping a separate lookup table mapping picture box control to uxSquare, which seems like an equally egregious hack.
Is there a standard pattern for identifying the parent object of a child object in a composite object, when you can't set data in the child object at creation? If I owned the child object, I would pass the parent object into its constructor and save it then. However, I don't have that kind of access to the Picture Box control.
Upvotes: 0
Views: 80
Reputation: 1244
You can subclass the picture box and pass in the row and column indices to the constructor.
public class UxPicBox : PictureBox {
public UxPicBox(int col, int row) : base() {
this.Col = col;
this.Row = row;
}
public int Col { get; set; }
public int Row { get; set; }
}
That way when the click event runs you can cast the sender as UxPicBox and get what you need to find the UxSquare.
Edit: This is an example of the click event
void UxPicBox_Click(object sender, EventArgs e) {
UxPicBox pb = (UxPicBox)sender;
MessageBox.Show(pb.Col.ToString() + " -- " + pb.Row.ToString());
}
Upvotes: 1