Использование объектов DrawingVisual
В этом разделе представлен обзор использования DrawingVisual объекты в WPF визуальном уровне.
Объект DrawingVisual
DrawingVisual — упрощенный класс, используемый для отрисовки фигур, изображений и текста. Этот класс считается упрощенным, так как не предоставляет средств для работы с разметкой и обработку событий, что повышает его производительность. Поэтому этот класс идеально подходит для фоновых рисунков или клипов.
Контейнер размещения DrawingVisual
Чтобы использовать DrawingVisual объектов, необходимо создать контейнер размещения для объектов. Объект контейнера размещения должен быть производным от FrameworkElement класс, который предоставляет макет и обработка событий поддерживает, что DrawingVisual класса отсутствует. Объект контейнера размещения не отображает видимых свойств, так как его основное назначение — включать дочерние объекты. Тем не менее Visibility свойство контейнера узла должно быть присвоено Visible; в противном случае будет отображаться ни один из его дочерних элементов.
При создании объекта контейнера размещения для визуальных объектов, вам необходимо сохранить ссылки визуального объекта в VisualCollection. Используйте Add метод для добавления визуального объекта в контейнер размещения. В следующем примере создается объект контейнера размещения, а также добавляются три визуальных объектов его VisualCollection.
// Create a host visual derived from the FrameworkElement class.
// This class provides layout, event handling, and container support for
// the child visual objects.
public class MyVisualHost : FrameworkElement
{
// Create a collection of child visual objects.
private VisualCollection _children;
public MyVisualHost()
{
_children = new VisualCollection(this);
_children.Add(CreateDrawingVisualRectangle());
_children.Add(CreateDrawingVisualText());
_children.Add(CreateDrawingVisualEllipses());
// Add the event handler for MouseLeftButtonUp.
this.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(MyVisualHost_MouseLeftButtonUp);
}
Note
Полный код примера, из которого был взят предыдущий пример кода, см. в разделе Проверка нажатия с помощью примера DrawingVisuals.
Создание объектов DrawingVisual
При создании DrawingVisual объекта, он не имеет графического содержимого. Можно добавить текст, графика или содержимое изображения путем извлечения объекта DrawingContext и рисования в него. Объект DrawingContext возвращается путем вызова RenderOpen метод DrawingVisual объекта.
Чтобы нарисовать прямоугольник в DrawingContext, использовать DrawRectangle метод DrawingContext объекта. Существуют аналогичные методы для рисования других объектов. После завершения рисования содержимое в DrawingContext, вызовите Close метод для закрытия DrawingContext и сохранить содержимое.
В следующем примере DrawingVisual создания объекта и прямоугольник в его DrawingContext.
// Create a DrawingVisual that contains a rectangle.
private DrawingVisual CreateDrawingVisualRectangle()
{
DrawingVisual drawingVisual = new DrawingVisual();
// Retrieve the DrawingContext in order to create new drawing content.
DrawingContext drawingContext = drawingVisual.RenderOpen();
// Create a rectangle and draw it in the DrawingContext.
Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80));
drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);
// Persist the drawing content.
drawingContext.Close();
return drawingVisual;
}
Создание переопределений для членов класса FrameworkElement
Объект контейнера размещения отвечает за управление своей коллекцией визуальных объектов. Для этого требуется, чтобы контейнера размещения реализован переопределения члена производного FrameworkElement класса.
Ниже приводятся два члена класса, которые необходимо переопределить.
GetVisualChild: Возвращает дочерний элемент по указанному индексу из коллекции дочерних элементов.
VisualChildrenCount: Получает количество визуальных дочерних элементов внутри этого элемента.
В следующем примере, переопределения для двух FrameworkElement члены реализуются.
// Provide a required override for the VisualChildrenCount property.
protected override int VisualChildrenCount
{
get { return _children.Count; }
}
// Provide a required override for the GetVisualChild method.
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index >= _children.Count)
{
throw new ArgumentOutOfRangeException();
}
return _children[index];
}
Поддержка проверки нажатия
Объект контейнера размещения может предоставлять обработку событий в случае, даже если он не содержит ни одного видимого свойства, однако его Visibility свойству должно быть присвоено Visible. Это позволяет создать процедуру обработки событий для контейнера размещения. Эта процедура сможет перехватывать события мыши, например отпускание левой кнопки мыши. Процедура обработки события можно реализовать проверку попадания путем вызова HitTest метод. Метод HitTestResultCallback параметр ссылается на определяемой пользователем процедуры, можно использовать для определения результата проверки нажатия.
В следующем примере реализована поддержка проверки нажатия для объекта узла контейнера и его дочерних объектов.
// Capture the mouse event and hit test the coordinate point value against
// the child visual objects.
void MyVisualHost_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// Retrieve the coordinates of the mouse button event.
System.Windows.Point pt = e.GetPosition((UIElement)sender);
// Initiate the hit test by setting up a hit test result callback method.
VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(myCallback), new PointHitTestParameters(pt));
}
// If a child visual object is hit, toggle its opacity to visually indicate a hit.
public HitTestResultBehavior myCallback(HitTestResult result)
{
if (result.VisualHit.GetType() == typeof(DrawingVisual))
{
if (((DrawingVisual)result.VisualHit).Opacity == 1.0)
{
((DrawingVisual)result.VisualHit).Opacity = 0.4;
}
else
{
((DrawingVisual)result.VisualHit).Opacity = 1.0;
}
}
// Stop the hit test enumeration of objects in the visual tree.
return HitTestResultBehavior.Stop;
}