RadiusX = 10, RadiusY = 10 };
break;
case SelectedShape.Line:
shapeToRender = new Line()
{
Stroke = Brushes.Blue,
StrokeThickness = 10,
X1 = 0, X2 = 50, Y1 = 0, Y2 = 50,
StrokeStartLineCap= PenLineCap.Triangle,
StrokeEndLineCap = PenLineCap.Round
};
break;
default:
return;
}
// Установить левый верхний угол для рисования на холсте.
Canvas.SetLeft(shapeToRender, e.GetPosition(canvasDrawingArea).X);
Canvas.SetTop(shapeToRender, e.GetPosition(canvasDrawingArea).Y);
// Нарисовать фигуру.
canvasDrawingArea.Children.Add(shapeToRender);
}
На заметку! Возможно, вы заметили, что объекты Ellipse
, Rectangle
и Line
, создаваемые в методе canvasDrawingArea_MouseLeftButtonDown()
, имеют те же настройки свойств, что и соответствующие определения XAML. Вполне ожидаемо, код можно упростить, но это требует понимания объектных ресурсов WPF, которые будут рассматриваться в главе 27.
В коде проверяется переменная-член _currentShape
с целью создания корректного объекта, производного от Shape
. Затем устанавливаются координаты левого верхнего угла внутри Canvas
с использованием входного объекта MouseButtonEventArgs
. Наконец, в коллекцию объектов UIElement
, поддерживаемую Canvas
, добавляется новый производный от Shape
объект. Если запустить программу прямо сейчас, то она должна позволить щелкать левой кнопкой мыши где угодно на холсте и визуализировать в позиции щелчка выбранную фигуру.
Удаление прямоугольников, эллипсов и линий с поверхности Canvas
Имея в распоряжении элемент Canvas
с коллекцией объектов, может возникнуть вопрос: как динамически удалить элемент, скажем, в ответ на щелчок пользователя правой кнопкой мыши на фигуре? Это делается с помощью класса VisualTreeHelper
из пространства имен System.Windows.Media
. Роль "визуальных деревьев" и "логических деревьев" более подробно объясняется в главе 27, а пока организуйте обработку события MouseRightButtonDown
объекта Canvas
и реализуйте соответствующий обработчик:
private void CanvasDrawingArea_MouseRightButtonDown(object sender,
MouseButtonEventArgs e)
{
// Сначала получить координаты x,y позиции,
// где пользователь выполнил щелчок.
Point pt = e.GetPosition((Canvas)sender);
// Использовать метод HitTestO класса VisualTreeHelper, чтобы
// выяснить, щелкнул ли пользователь на элементе внутри Canvas.
HitTestResult result = VisualTreeHelper.HitTest(canvasDrawingArea, pt);
// Если переменная result не равна null, то щелчок произведен на фигуре.
if (result != null)
{
// Получить фигуру, на которой совершен щелчок, и удалить ее из Canvas.
canvasDrawingArea.Children.Remove(result.VisualHit as Shape);
}
}
Метод начинается с получения точных координат (х
, у
) позиции, где пользователь щелкнул внутри Canvas
, и проверки попадания посредством статического метода VisualTreeHelper.HitTest()
. Возвращаемое значение — объект HitTestResult
— будет установлено в null
, если пользователь выполнил щелчок не на UIElement
внутри Canvas
. Если значение HitTestResult
не равно null
, тогда с помощью свойства VisualHit
можно получить объект UIElement
, на котором был совершен щелчок, и привести его к типу, производному от Shape
(вспомните, что Canvas
может содержать любой UIElement
, а не только фигуры). Детали, связанные с "визуальным деревом", будут изложены в главе 27.
На заметку! По умолчанию метод VisualTreeHelper.HitTest()
возвращает объект UIElement
самого верхнего уровня, на котором совершен щелчок, и не предоставляет информацию о других объектах, расположенных под ним (т.е. перекрытых в Z-порядке).