Язык программирования C#9 и платформа .NET5
Шрифт:
}
На заметку! Возможно, вы заметили, что объекты
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-порядке). В результате внесенных модификаций должна появиться возможность добавления фигуры на
Canvas
щелчком левой кнопкой мыши и ее удаления щелчком правой кнопкой мыши. До настоящего момента вы применяли объекты типов, производных от
Shape
, для визуализации содержимого элементов RadioButton
с использованием разметки XAML и заполняли Canvas
в коде С#. Во время исследования
UIElement
. А пока давайте рассмотрим оставшиеся члены пространства имен System.Windows.Shapes
. Работа с элементами Polyline и Polygon
В текущем примере используются только три класса, производных от
Shape
. Остальные дочерние классы (Polyline
, Polygon
и Path
) чрезвычайно трудно корректно визуализировать без инструментальной поддержки (такой как инструмент Blend для Visual Studio или другие инструменты, которые могут создавать векторную графику) — просто потому, что они требуют определения большого количества точек для своего выходного представления. Ниже представлен краткий обзор остальных типов Shapes
. Тип
Polyline
позволяет определить коллекцию координат (х
, у
) (через свойство Points
) для рисования последовательности линейных сегментов, не требующих замыкания. Тип Polygon
похож, но запрограммирован так, что всегда замыкает контур, соединяя начальную точку с конечной, и заполняет внутреннюю область с помощью указанной кисти. Предположим, что в редакторе Kaxaml создан следующий элемент StackPanel
:
<!-- Элемент Polyline не замыкает автоматически конечные точки -->
<Polyline Stroke ="Red" StrokeThickness ="20" StrokeLineJoin ="Round"
Points ="10,10 40,40
10,90 300,50"/>
<!-- Элемент Polygon всегда замыкает конечные точки -->
<Polygon Fill ="AliceBlue" StrokeThickness ="5" Stroke ="Green"
Points ="40,10 70,80 10,50" />
На рис. 26.2 показан визуализированный вывод в Kaxaml.
Работа с элементом Path
Применяя только типы
Rectangle
, Ellipse
, Polygon
, Polyline
и Line
, нарисовать детализированное двумерное векторное изображение было бы исключительно трудно, т.к. упомянутые примитивы не позволяют легко фиксировать графические данные, подобные кривым, объединениям перекрывающихся данных и т.д. Последний производный от Shape
класс, Path
, предоставляет возможность определения сложных двумерных графических данных в виде коллекции независимых геометрических объектов. После того, как коллекция таких геометрических объектов определена, ее можно присвоить свойству Data
класса Path
, где она будет использоваться для визуализации сложного двумерного изображения. Свойство
Data
получает объект класса, производного от System.Windows.Media.Geometry
, который содержит ключевые члены, кратко описанные в табл. 26.2. Классы, которые расширяют класс
Geometry
(табл. 26.3), выглядят очень похожими на свои аналоги, производные от Shape
. Например, класс EllipseGeometry
имеет члены, подобные членам класса Ellipse
. Крупное отличие связано с тем, что производные от Geometry
классы не знают, каким образом визуализировать себя напрямую, поскольку они не являются UIElement
. Взамен классы, производные от Geometry
, представляют всего лишь коллекцию данных о точках, которая указывает объекту Path
, как их визуализировать.
Поделиться:
Популярные книги
Солнечный корт
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
О, мой бомж
1. Несвятая троица
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Возвышение Меркурия. Книга 2
2. Меркурий
Фантастика:
фэнтези
5.00
рейтинг книги
Вы не прошли собеседование
1. Укротить миллионера
Любовные романы:
короткие любовные романы
5.00
рейтинг книги
Метаморфозы Катрин
Фантастика:
фэнтези
8.26
рейтинг книги
Эволюция мага
2. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Попаданка для Дракона, или Жена любой ценой
Любовные романы:
любовно-фантастические романы
7.17
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Сумеречный Стрелок 5
5. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 17
17. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Переиграть войну! Пенталогия
Переиграть войну!
Фантастика:
героическая фантастика
альтернативная история
8.25
рейтинг книги
Волков. Гимназия №6
1. Волков
Фантастика:
попаданцы
альтернативная история
аниме
7.00
рейтинг книги
Картофельное счастье попаданки
Фантастика:
фэнтези
5.00