Я думаю, что я сделал это (с вашей помощью, чтобы начать меня) ...
Во-первых, я переместил обработку событий перемещения на холст вместо каждого эллипса. Это хорошо и плохо с точки зрения ООП. По крайней мере, когда обработка событий мыши является обязанностью HolePattern, чтобы установить его на каждое Отверстие (эллипс, который является визуальным элементом Отверстия), он абстрагируется так, что любой потребитель моего HolePattern получит эту функцию автоматически. Однако, переместив его в основной код пользовательского интерфейса, я теперь имею дело с событием мыши на холсте на более высоком уровне. Но это еще не все плохо. Мы могли бы обсудить эту часть в течение нескольких дней.
Дело в том, что я разработал способ создания «поля погрешности», когда выбираю что-то на холсте с помощью мыши, а затем читаю Отверстие, к которому принадлежит выбранный Эллипс, и затем я могу прочитать HolePattern, который Отверстие принадлежит, и весь мой пользовательский интерфейс (ListView, текстовые поля, координатная сетка) обновляются ВСЕМ существующей привязкой XAML, а Canvas обновляется одним вызовом существующего метода для регенерации холста.
Если честно, я не могу поверить, что я все это понял (с вашей помощью и другими, конечно). Это такое классное чувство - видеть это и видеть, как оно происходит.
Проверьте основной код здесь:
void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
int ClickMargin = 2;
Point ClickedPoint = e.GetPosition(canvas1);
Point p1 = new Point(ClickedPoint.X - ClickMargin, ClickedPoint.Y - ClickMargin);
Point p2 = new Point(ClickedPoint.X - ClickMargin, ClickedPoint.Y + ClickMargin);
Point p3 = new Point(ClickedPoint.X + ClickMargin, ClickedPoint.Y + ClickMargin);
Point p4 = new Point(ClickedPoint.X + ClickMargin, ClickedPoint.Y - ClickMargin);
var PointPickList = new Collection<Point>();
PointPickList.Add(ClickedPoint);
PointPickList.Add(p1);
PointPickList.Add(p2);
PointPickList.Add(p3);
PointPickList.Add(p4);
foreach (Point p in PointPickList)
{
HitTestResult SelectedCanvasItem = System.Windows.Media.VisualTreeHelper.HitTest(canvas1, p);
if (SelectedCanvasItem.VisualHit.GetType() == typeof(Ellipse))
{
var SelectedEllipseTag = SelectedCanvasItem.VisualHit.GetValue(Ellipse.TagProperty);
if (SelectedEllipseTag!=null && SelectedEllipseTag.GetType().BaseType == typeof(Hole))
{
Hole SelectedHole = (Hole)SelectedEllipseTag;
SetActivePattern(SelectedHole.ParentPattern);
SelectedHole.ParentPattern.CurrentHole = SelectedHole;
}
}
}
}