У меня была идея, аналогичная SM Kamran: у вас может быть свойство Canvas
в вашем классе Shape
, чтобы указать холст, к которому принадлежит эта фигура, и коллекция Shapes
в вашем классе Canvas
для провести коллекцию фигур:
Вот краткий пример:
interface ICanvas
{
// It's a good thing to use an interface
// in this phase. It will allow you greater
// freedom later.
}
class Canvas : ICanvas
{
private Shape.ShapeCollection _shapes;
public Collection<Shape> Shapes
{
get { return _shapes; }
}
public Canvas()
{
_shapes = new Shape.ShapeCollection(this);
}
}
class Shape
{
public class ShapeCollection : Collection<Shape>
{
private readonly ICanvas _parent;
public ShapeCollection(ICanvas parent)
{
_parent = parent;
}
protected override void InsertItem(int index, Shape item)
{
item._canvas = _parent;
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
this[index]._canvas = null;
base.RemoveItem(index);
}
protected override void SetItem(int index, Shape item)
{
RemoveAt(index);
InsertItem(index, item);
}
protected override void ClearItems()
{
while (this.Count != 0)
this.RemoveAt(this.Count - 1);
}
}
private ICanvas _canvas;
public ICanvas Canvas
{
get { return _canvas; }
}
}
При добавлении фигуры на холст свойство Shape.Canvas
будет обновляться автоматически:
Canvas canvas = new Canvas();
Shape circle = new Shape();
canvas.Shapes.Add(circle);
Обратите внимание, что ShapeCollection
- это вложенный класс внутри Shape
, потому что это единственный способ установить личное свойство _canvas
.
Универсальные коллекции (например, Collection<Shape>
) часто используются для схожих проблем, поскольку вы можете переопределить их свойства InsertItem
/ RemoveItem
, чтобы добавить пользовательские функции при изменении коллекции.
Вы также можете создать синглтон «Пустой / Стандартный холст» и использовать его вместо нуля, когда фигуре не назначен реальный холст (просто чтобы не проверять, является ли Shape.Canvas
нулевым каждый раз).