Общие сведения об отрисовке графики в WPFWPF Graphics Rendering Overview

В этом разделе приведены общие сведения о визуальном слое WPFWPF.This topic provides an overview of the WPFWPF visual layer. Основное внимание в нем уделено роли класса Visual в поддержке отрисовки в модели WPFWPF.It focuses on the role of the Visual class for rendering support in the WPFWPF model.

Роль объекта VisualRole of the Visual Object

Класс Visual — это базовая абстракция, и каждый объект FrameworkElement является производным от него.The Visual class is the basic abstraction from which every FrameworkElement object derives. Эта абстракция также служит точкой входа для написания новых элементов управления WPFWPF, и во многих случаях ее можно рассматривать как аналог дескриптора окна (HWND) в модели приложений Win32.It also serves as the entry point for writing new controls in WPFWPF, and in many ways can be thought of as the window handle (HWND) in the Win32 application model.

Объект Visual — это основной объект WPFWPF, главная роль которого заключается в поддержке отрисовки.The Visual object is a core WPFWPF object, whose primary role is to provide rendering support. Элементы управления пользовательского интерфейса, такие как Button и TextBox, являются производными от класса Visual и используют его для сохранения данных отрисовки.User interface controls, such as Button and TextBox, derive from the Visual class, and use it for persisting their rendering data. Объект Visual обеспечивает поддержку следующих функций:The Visual object provides support for:

  • Вывод: Отображение сохраненного сериализованного содержимого визуального элемента.Output display: Rendering the persisted, serialized drawing content of a visual.

  • Преобразования. Выполнение преобразования визуального элемента.Transformations: Performing transformations on a visual.

  • Вырезая Предоставление поддержки области отсечения для визуального элемента.Clipping: Providing clipping region support for a visual.

  • Проверка нажатия: Определение, содержится ли координата или геометрия в границах визуального элемента.Hit testing: Determining whether a coordinate or geometry is contained within the bounds of a visual.

  • Вычисления ограничивающих прямоугольников: Определение ограничивающего прямоугольника визуального элемента.Bounding box calculations: Determining the bounding rectangle of a visual.

Однако объект Visual не включает поддержку функций, не относящихся к отрисовке, например:However, the Visual object does not include support for non-rendering features, such as:

  • Обработка событийEvent handling

  • МакетLayout

  • СтилиStyles

  • Привязка данныхData binding

  • ГлобализацияGlobalization

Visual предоставляется в виде открытого абстрактного класса, от которого должны наследоваться дочерние классы.Visual is exposed as a public abstract class from which child classes must be derived. На следующем рисунке показана иерархия визуальных объектов, которые предоставляются в WPFWPF.The following illustration shows the hierarchy of the visual objects that are exposed in WPFWPF.

Схема классов, производных от Visual-объекта

Класс DrawingVisualDrawingVisual Class

DrawingVisual — упрощенный класс, используемый для отрисовки фигур, изображений и текста.The DrawingVisual is a lightweight drawing class that is used to render shapes, images, or text. Этот класс считается упрощенным, так как не предоставляет средств для работы с разметкой и обработку событий, что повышает его производительность.This class is considered lightweight because it does not provide layout or event handling, which improves its runtime performance. Поэтому этот класс идеально подходит для фоновых рисунков или клипов.For this reason, drawings are ideal for backgrounds and clip art. DrawingVisual может быть использован для создания пользовательского визуального объекта.The DrawingVisual can be used to create a custom visual object. Дополнительные сведения см. в разделе Использование объектов DrawingVisual.For more information, see Using DrawingVisual Objects.

Класс Viewport3DVisualViewport3DVisual Class

Viewport3DVisual обеспечивает связь между двухмерными Visual и объектами Visual3D.The Viewport3DVisual provides a bridge between 2D Visual and Visual3D objects. Класс Visual3D является базовым классом для всех трехмерных визуальных элементов.The Visual3D class is the base class for all 3D visual elements. Для Viewport3DVisual необходимо определить значения Camera и Viewport.The Viewport3DVisual requires that you define a Camera value and a Viewport value. Камера (Camera) позволяет просмотреть сцену.The camera allows you to view the scene. Окно просмотра (Viewport) определяет, где проекция преобразуется в двумерную поверхность.The viewport establishes where the projection maps onto the 2D surface. Дополнительные сведения о трехмерной графике в WPFWPF см. в разделе Общие сведения о трехмерной графике.For more information on 3D in WPFWPF, see 3-D Graphics Overview.

Класс ContainerVisualContainerVisual Class

Класс ContainerVisual используется как контейнер для коллекции объектов Visual.The ContainerVisual class is used as a container for a collection of Visual objects. Класс DrawingVisual является производным от класса ContainerVisual, поэтому он может содержать коллекцию визуальных объектов.The DrawingVisual class derives from the ContainerVisual class, allowing it to contain a collection of visual objects.

Рисование содержимого в объектах VisualDrawing Content in Visual Objects

Объект Visual хранит свои данные отрисовки в виде списка инструкций векторной графики.A Visual object stores its render data as a vector graphics instruction list. Каждый элемент в списке инструкций представляет низкоуровневый набор графических данных и связанных ресурсов в сериализованном формате.Each item in the instruction list represents a low-level set of graphics data and associated resources in a serialized format. Существует четыре различных типа данных отрисовки, которые могут включать графическое содержимое.There are four different types of render data that can contain drawing content.

Тип содержимого для отрисовкиDrawing content type ОписаниеDescription
Векторная графикаVector graphics Представляет векторные графические данные и все связанные сведения о Brush и Pen.Represents vector graphics data, and any associated Brush and Pen information.
ИзображениеImage Представляет изображение в регионе, определенном Rect.Represents an image within a region defined by a Rect.
ГлифGlyph Представляет рисунок, отображающий объект GlyphRun, который представляет собой последовательность глифов для указанного ресурса шрифта.Represents a drawing that renders a GlyphRun, which is a sequence of glyphs from a specified font resource. Таким образом представляется текст.This is how text is represented.
ВидеоVideo Представляет рисунок, отображающий видео.Represents a drawing that renders video.

DrawingContext позволяет заполнять Visual визуальным содержимым.The DrawingContext allows you to populate a Visual with visual content. При использовании команд рисования объекта DrawingContext фактически происходит сохранение набора данных отрисовки, которые позже будут использоваться графической системой; рисование на экране в режиме реального времени не выполняется.When you use a DrawingContext object's draw commands, you are actually storing a set of render data that will later be used by the graphics system; you are not drawing to the screen in real-time.

При создании элементов управления WPFWPF, например Button, элемент управления неявно создает данные для своей отрисовки.When you create a WPFWPF control, such as a Button, the control implicitly generates render data for drawing itself. Например, установка свойства Content элемента управления Button заставляет его сохранить представление отрисовки для глифа.For example, setting the Content property of the Button causes the control to store a rendering representation of a glyph.

Объект Visual описывает свое содержимое в виде одного или нескольких объектов Drawing, содержащихся в DrawingGroup.A Visual describes its content as one or more Drawing objects contained within a DrawingGroup. В DrawingGroup также описываются маски непрозрачности, преобразования, эффекты точечного рисунка и другие операции, применяемые к его содержимому.A DrawingGroup also describes opacity masks, transforms, bitmap effects, and other operations that are applied to its contents. При отрисовке содержимого операции DrawingGroup применяются в следующем порядке: OpacityMask, Opacity, BitmapEffect, ClipGeometry, GuidelineSet, а затем Transform.DrawingGroup operations are applied in the following order when content is rendered: OpacityMask, Opacity, BitmapEffect, ClipGeometry, GuidelineSet, and then Transform.

Ниже показан порядок, в котором операции DrawingGroup применяются при отрисовке.The following illustration shows the order in which DrawingGroup operations are applied during the rendering sequence.

DrawingGroup порядок операцийDrawingGroup order of operations
Порядок операций для DrawingGroupOrder of DrawingGroup operations

Дополнительные сведения см. в разделе Обзор объектов Drawing.For more information, see Drawing Objects Overview.

Отображение содержимого на визуальном уровнеDrawing Content at the Visual Layer

Вы никогда непосредственно не создаете экземпляр DrawingContext, однако можете получить контекст рисования с помощью определенных методов, например DrawingGroup.Open и DrawingVisual.RenderOpen.You never directly instantiate a DrawingContext; you can, however, acquire a drawing context from certain methods, such as DrawingGroup.Open and DrawingVisual.RenderOpen. В следующем примере DrawingContext извлекается из DrawingVisual и используется для рисования прямоугольника.The following example retrieves a DrawingContext from a DrawingVisual and uses it to draw a rectangle.

// 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;
}
' Create a DrawingVisual that contains a rectangle.
Private Function CreateDrawingVisualRectangle() As DrawingVisual
    Dim drawingVisual As New DrawingVisual()

    ' Retrieve the DrawingContext in order to create new drawing content.
    Dim drawingContext As DrawingContext = drawingVisual.RenderOpen()

    ' Create a rectangle and draw it in the DrawingContext.
    Dim rect As New Rect(New Point(160, 100), New Size(320, 80))
    drawingContext.DrawRectangle(Brushes.LightBlue, CType(Nothing, Pen), rect)

    ' Persist the drawing content.
    drawingContext.Close()

    Return drawingVisual
End Function

Перечисление содержимого рисования на визуальном уровнеEnumerating Drawing Content at the Visual Layer

Наряду с другими своими возможностями, объекты Drawing также предоставляют объектную модель для перечисления содержимого Visual.In addition to their other uses, Drawing objects also provide an object model for enumerating the contents of a Visual.

Примечание

При перечислении содержимого визуального элемента извлекаются объекты Drawing, а не базовое представление данных отрисовки в виде списка инструкций векторной графики.When you are enumerating the contents of the visual, you are retrieving Drawing objects, and not the underlying representation of the render data as a vector graphics instruction list.

В следующем примере метод GetDrawing используется для извлечения значения DrawingGroup из Visual и перечисления содержимого группы.The following example uses the GetDrawing method to retrieve the DrawingGroup value of a Visual and enumerate it.

public void RetrieveDrawing(Visual v)
{
    DrawingGroup drawingGroup = VisualTreeHelper.GetDrawing(v);
    EnumDrawingGroup(drawingGroup);
}

// Enumerate the drawings in the DrawingGroup.
public void EnumDrawingGroup(DrawingGroup drawingGroup)
{
    DrawingCollection dc = drawingGroup.Children;

    // Enumerate the drawings in the DrawingCollection.
    foreach (Drawing drawing in dc)
    {
        // If the drawing is a DrawingGroup, call the function recursively.
        if (drawing is DrawingGroup group)
        {
            EnumDrawingGroup(group);
        }
        else if (drawing is GeometryDrawing)
        {
            // Perform action based on drawing type.  
        }
        else if (drawing is ImageDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is GlyphRunDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is VideoDrawing)
        {
            // Perform action based on drawing type.
        }
    }
}

Использование визуальных объектов для создания элементов управленияHow Visual Objects are Used to Build Controls

Многие из объектов в WPFWPF состоят из других визуальных объектов, то есть они могут содержать различные иерархии объектов-потомков.Many of the objects in WPFWPF are composed of other visual objects, meaning they can contain varying hierarchies of descendant objects. Многие элементы пользовательского интерфейса в WPFWPF, например элементы управления, состоят из множества визуальных объектов, которые представляют различные типы отрисовываемых элементов.Many of the user interface elements in WPFWPF, such as controls, are composed of multiple visual objects, representing different types of rendering elements. Например, элемент управления Button может содержать ряд других объектов, в том числе ClassicBorderDecorator, ContentPresenter и TextBlock.For example, the Button control can contain a number of other objects, including ClassicBorderDecorator, ContentPresenter, and TextBlock.

В следующем коде показано определение элемента управления Button в разметке.The following code shows a Button control defined in markup.

<Button Click="OnClick">OK</Button>

Если бы мы перечислили визуальные объекты, составляющие стандартный элемент управления Button, обнаружилась бы показанная ниже иерархия визуальных объектов:If you were to enumerate the visual objects that comprise the default Button control, you would find the hierarchy of visual objects illustrated below:

Схема иерархии визуального дерева

Элемент управления Button содержит элемент ClassicBorderDecorator, который, в свою очередь, содержит элемент ContentPresenter.The Button control contains a ClassicBorderDecorator element, which in turn, contains a ContentPresenter element. Элемент ClassicBorderDecorator отвечает за рисование границ и фона для Button.The ClassicBorderDecorator element is responsible for drawing a border and a background for the Button. Элемент ContentPresenter отвечает за отображение содержимого Button.The ContentPresenter element is responsible for displaying the contents of the Button. В данном случае, поскольку отображается текст, элемент ContentPresenter содержит элемент TextBlock.In this case, since you are displaying text, the ContentPresenter element contains a TextBlock element. Тот факт, что элемент управления Button использует ContentPresenter, означает, что его содержимое можно представить в виде других элементов, например Image, или геометрического объекта, например EllipseGeometry.The fact that the Button control uses a ContentPresenter means that the content could be represented by other elements, such as an Image or a geometry, such as an EllipseGeometry.

Шаблоны элементов управленияControl Templates

Ключевую роль в развертывании элементов управления в иерархию играет ControlTemplate.The key to the expansion of a control into a hierarchy of controls is the ControlTemplate. Шаблон элемента управления определяет его визуальную иерархию по умолчанию.A control template specifies the default visual hierarchy for a control. При явной ссылке на элемент управления вы неявно ссылаетесь на его визуальную иерархию.When you explicitly reference a control, you implicitly reference its visual hierarchy. Для изменения внешнего вида элемента управления вы можете переопределить значения по умолчанию для его шаблона.You can override the default values for a control template to create a customized visual appearance for a control. Например, можно изменить значение цвета фона элемента управления Button так, чтобы использовалось значение линейного градиента цвета вместо значения сплошного цвета.For example, you could modify the background color value of the Button control so that it uses a linear gradient color value instead of a solid color value. Дополнительные сведения см. в разделе Стили и шаблоны кнопок.For more information, see Button Styles and Templates.

Элемент пользовательского интерфейса, например Button элемент управления, содержит несколько списков инструкций векторной графики, описывающих все определение отрисовки элемента управления.A user interface element, such as a Button control, contains several vector graphics instruction lists that describe the entire rendering definition of a control. В следующем коде показано определение элемента управления Button в разметке.The following code shows a Button control defined in markup.

<Button Click="OnClick">
  <Image Source="images\greenlight.jpg"></Image>
</Button>

Если перечислить визуальные объекты и списки инструкций векторной графики, которые составляют элемент управления Button, обнаружится показанная ниже иерархия объектов:If you were to enumerate the visual objects and vector graphics instruction lists that comprise the Button control, you would find the hierarchy of objects illustrated below:

Схема визуального дерева и отрисовки данных

Элемент управления Button содержит элемент ClassicBorderDecorator, который, в свою очередь, содержит элемент ContentPresenter.The Button control contains a ClassicBorderDecorator element, which in turn, contains a ContentPresenter element. ClassicBorderDecorator Элемент отвечает за рисование всех дискретных графических элементов, составляющих границу и фон кнопки.The ClassicBorderDecorator element is responsible for drawing all the discrete graphic elements that make up the border and background of a button. Элемент ContentPresenter отвечает за отображение содержимого Button.The ContentPresenter element is responsible for displaying the contents of the Button. В этом случае, поскольку отображается изображение, ContentPresenter элемент Image содержит элемент.In this case, since you are displaying an image, the ContentPresenter element contains a Image element.

При работе с иерархией визуальных объектов и списками инструкций векторной графики следует учитывать несколько моментов.There are a number of points to note about the hierarchy of visual objects and vector graphics instruction lists:

  • Порядок иерархии представляет порядок отрисовки графической информации.The ordering in the hierarchy represents the rendering order of the drawing information. От корневого визуального элемента проход дочерних элементов осуществляется слева направо и сверху вниз.From the root visual element, child elements are traversed, left to right, top to bottom. Если у элемента есть дочерние визуальные элементы, они проходятся до элементов того же уровня.If an element has visual child elements, they are traversed before the element’s siblings.

  • Неконечные элементы в иерархии, например ContentPresenter, используются для хранения дочерних элементов — они не содержат списков инструкций.Non-leaf node elements in the hierarchy, such as ContentPresenter, are used to contain child elements—they do not contain instruction lists.

  • Если визуальный элемент содержит как список инструкций векторной графики, так и визуальные дочерние объекты, то список инструкций в родительском визуальном элементе выполняется перед тем, как будут прорисованы любые визуальные дочерние объекты.If a visual element contains both a vector graphics instruction list and visual children, the instruction list in the parent visual element is rendered before drawings in any of the visual child objects.

  • Элементы в списке инструкций векторной графики обрабатываются слева направо.The items in the vector graphics instruction list are rendered left to right.

Визуальное деревоVisual Tree

Визуальное дерево содержит все визуальные элементы, содержащиеся в пользовательском интерфейсе приложения.The visual tree contains all visual elements used in an application's user interface. Поскольку визуальный элемент содержит сохраняемую графическую информацию, визуальное дерево можно представить как граф сцены, содержащий все сведения об отрисовке, необходимые для формирования данных, выводимых на устройство отображения.Since a visual element contains persisted drawing information, you can think of the visual tree as a scene graph, containing all the rendering information needed to compose the output to the display device. Это дерево представляет собой совокупность всех визуальных элементов, создаваемых непосредственно в приложении (в коде или в разметке).This tree is the accumulation of all visual elements created directly by the application, whether in code or in markup. Визуальное дерево также содержит все визуальные элементы, создаваемые путем расширения шаблона элементов, например элементы управления и объекты данных.The visual tree also contains all visual elements created by the template expansion of elements such as controls and data objects.

В следующем коде показан элемент StackPanel, определенный в разметке.The following code shows a StackPanel element defined in markup.

<StackPanel>
  <Label>User name:</Label>
  <TextBox />
  <Button Click="OnClick">OK</Button>
</StackPanel>

Если перечислить визуальные объекты, которые составляют элемент StackPanel в примере разметки, обнаружится показанная ниже иерархия визуальных объектов:If you were to enumerate the visual objects that comprise the StackPanel element in the markup example, you would find the hierarchy of visual objects illustrated below:

Схема иерархии визуального дерева

Порядок отрисовкиRendering Order

Визуальное дерево определяет порядок отрисовки визуальных элементов и графических объектов WPFWPF.The visual tree determines the rendering order of WPFWPF visual and drawing objects. Обработка начинается с корневого визуального элемента, самого верхнего узла в визуальном дереве.The order of traversal starts with the root visual, which is the top-most node in the visual tree. Затем обрабатываются дочерние элементы корневого визуального элемента слева направо.The root visual’s children are then traversed, left to right. Если у визуального элемента есть дочерние элементы, они обрабатываются перед элементами, находящимися на одном уровне с визуальным элементом.If a visual has children, its children are traversed before the visual’s siblings. Это означает, что содержимое дочерних визуальных элементов отображается перед содержимым самого визуального элемента.This means that the content of a child visual is rendered in front of the visual's own content.

Схема порядка отрисовки визуального дерева

Корневой визуальный элементRoot Visual

Корневой визуальный элемент — это самый верхний элемент в иерархии визуального дерева.The root visual is the top-most element in a visual tree hierarchy. В большинстве приложений базовым классом корневого визуального элемента является либо Window, либо NavigationWindow.In most applications, the base class of the root visual is either Window or NavigationWindow. Однако при размещении визуальных объектов в приложении Win32 корневым визуальным элементом будет самый верхний визуальный элемент в окне Win32.However, if you were hosting visual objects in a Win32 application, the root visual would be the top-most visual you were hosting in the Win32 window. Дополнительные сведения см. в статье Руководство по размещению визуальных объектов в приложении Win32.For more information, see Tutorial: Hosting Visual Objects in a Win32 Application.

Связь с логическом деревомRelationship to the Logical Tree

Логическое дерево в WPFWPF представляет элементы приложения во время выполнения.The logical tree in WPFWPF represents the elements of an application at run time. Хотя этим деревом нельзя управлять напрямую, с помощью этой схемы удобно представить наследование свойств и маршрутизацию событий.Although you do not manipulate this tree directly, this view of the application is useful for understanding property inheritance and event routing. В отличие от визуального дерева, логическое дерево может представлять и невизуальные объекты, например ListItem.Unlike the visual tree, the logical tree can represent non-visual data objects, such as ListItem. Во многих случаях логическое дерево приближается к определению разметки приложения.In many cases, the logical tree maps very closely to an application's markup definitions. В следующем коде показан элемент DockPanel, определенный в разметке.The following code shows a DockPanel element defined in markup.

<DockPanel>
  <ListBox>
    <ListBoxItem>Dog</ListBoxItem>
    <ListBoxItem>Cat</ListBoxItem>
    <ListBoxItem>Fish</ListBoxItem>
  </ListBox>
  <Button Click="OnClick">OK</Button>
</DockPanel>

Если перечислить логические объекты, которые составляют элемент DockPanel в примере разметки, обнаружится иерархия логических объектов, показанная ниже:If you were to enumerate the logical objects that comprise the DockPanel element in the markup example, you would find the hierarchy of logical objects illustrated below:

Схема дереваTree diagram
Схема логического дереваDiagram of logical tree

Визуальное дерево и логическое дерево синхронизируются с текущим набором элементов приложения, отражая добавление, удаление или изменение элементов.Both the visual tree and logical tree are synchronized with the current set of application elements, reflecting any addition, deletion, or modification of elements. Однако эти деревья отражают различные представления приложения.However, the trees present different views of the application. В отличие от визуального дерева, в логическом дереве не ракрываются ContentPresenter элементов управления.Unlike the visual tree, the logical tree does not expand a control's ContentPresenter element. Это означает, что между логическим деревом и визуальным деревом для одного и того же набора объектов нет прямого однозначного соответствия.This means there is not a direct one-to-one correspondence between a logical tree and a visual tree for the same set of objects. На самом деле, вызов метода GetChildren объекта LogicalTreeHelper и метода GetChild объекта VisualTreeHelper с одним и тем же элементом в качестве параметра дает разные результаты.In fact, invoking the LogicalTreeHelper object's GetChildren method and the VisualTreeHelper object's GetChild method using the same element as a parameter yields differing results.

Дополнительные сведения о логическом дереве см. в разделе Деревья в WPF.For more information on the logical tree, see Trees in WPF.

Просмотр визуального дерева с помощью XamlPadViewing the Visual Tree with XamlPad

Средство WPFWPF XamlPad позволяет просматривать и изучать визуальное дерево, соответствующее текущему содержимому XAMLXAML.The WPFWPF tool, XamlPad, provides an option for viewing and exploring the visual tree that corresponds to the currently defined XAMLXAML content. Для отображения визуального дерева нажмите кнопку Показать визуальное дерево.Click the Show Visual Tree button on the menu bar to display the visual tree. Ниже показано расширение содержимого XAMLXAML в узлы визуального дерева на панели Обозреватель визуального дерева XamlPad.The following illustrates the expansion of XAMLXAML content into visual tree nodes in the Visual Tree Explorer panel of XamlPad:

Панель обозревателя визуального дерева в XamlPad

Обратите внимание, что каждый из элементов управления Label, TextBox и Button отображает отдельную иерархию визуальных объектов в панели Обозреватель визуального дерева XamlPad.Notice how the Label, TextBox, and Button controls each display a separate visual object hierarchy in the Visual Tree Explorer panel of XamlPad. Это обусловлено тем, что элементы управления WPFWPF имеют шаблон ControlTemplate, который содержит визуальное дерево этого элемента управления.This is because WPFWPF controls have a ControlTemplate that contains the visual tree of that control. При явной ссылке на элемент управления вы неявно ссылаетесь на его визуальную иерархию.When you explicitly reference a control, you implicitly reference its visual hierarchy.

Профилирование производительности для объекта VisualProfiling Visual Performance

В состав WPFWPF входит пакет инструментов для профилирования производительности, с помощью которых можно проанализировать поведение приложения во время выполнения и определить, каким образом можно повысить производительность.WPFWPF provides a suite of performance profiling tools that allow you to analyze the run-time behavior of your application and determine the types of performance optimizations you can apply. Средство Visual Profiler предоставляет подробные данные о производительности в удобном графическом формате, сопоставляя их напрямую с визуальным деревом приложения.The Visual Profiler tool provides a rich, graphical view of performance data by mapping directly to the application's visual tree. На этом снимке экрана показан раздел Использование ЦП средства Visual Profiler. В этом разделе вы можете получить точное представление об использовании объектом служб WPFWPF, таких как отрисовка и разметка.In this screenshot, the CPU Usage section of the Visual Profiler gives you a precise breakdown of an object's use of WPFWPF services, such as rendering and layout.

Отображение выходных данных визуального профилировщикаVisual Profiler display output
Отображение данных Visual ProfilerVisual Profiler display output

Поведение отрисовки для объекта VisualVisual Rendering Behavior

WPFWPF включает несколько возможностей, влияющих на отрисовку визуальных объектов: абстрактный графический режим, векторная графика и аппаратно независимая графика.introduces several features that affect the rendering behavior of visual objects: retained mode graphics, vector graphics, and device independent graphics.

Абстрактный графический режимRetained Mode Graphics

Для понимания роли объекта Visual необходимо хорошо представлять различие между системами с непосредственным и абстрактным графическими режимами.One of the keys to understanding the role of the Visual object is to understand the difference between immediate mode and retained mode graphics systems. В стандартном приложении Win32 на основе GDI или GDI+ используется непосредственный графический режим.A standard Win32 application based on GDI or GDI+ uses an immediate mode graphics system. Это означает, что приложение отвечает за перерисовку той части клиентской области, которая стала недействительной из-за таких действий, как изменение размера окна или изменение внешнего вида объекта.This means that the application is responsible for repainting the portion of the client area that is invalidated, due to an action such as a window being resized, or an object changing its visual appearance.

Схема последовательности отрисовки Win32

В WPFWPF, напротив, используется абстрактный графический режим.In contrast, WPFWPF uses a retained mode system. Это означает, что в объектах приложения, у которых есть внешний облик, определяется набор сериализованных графических данных.This means application objects that have a visual appearance define a set of serialized drawing data. После определения графических данных система отвечает на все запросы перерисовки для отрисовки объектов приложения.Once the drawing data is defined, the system is responsible thereafter for responding to all repaint requests for rendering the application objects. Даже во время выполнения можно изменять или создавать объекты приложения, при этом система будет обрабатывать запросы на перерисовку.Even at run time, you can modify or create application objects, and still rely on the system for responding to paint requests. Преимущество абстрактного режима состоит в том, что данные отрисовки всегда сохраняются приложением в сериализованном виде, при этом за отрисовку отвечает система.The power in a retained mode graphics system is that drawing information is always persisted in a serialized state by the application, but rendering responsibility left to the system. На следующей схеме показано, как приложение полагается на WPFWPF в обработке запросов на отрисовку.The following diagram shows how the application relies on WPFWPF for responding to paint requests.

Схема последовательности отрисовки WPF

Интеллектуальная перерисовкаIntelligent Redrawing

Одним из основных преимуществ использования абстрактного графического режима является то, что WPFWPF может эффективно оптимизировать элементы приложения, которые требуют перерисовки.One of the biggest benefits in using retained mode graphics is that WPFWPF can efficiently optimize what needs to be redrawn in the application. Даже при наличии сложной сцены с различными уровнями прозрачности разработчикам обычно не нужно писать специальный код для оптимизации перерисовки.Even if you have a complex scene with varying levels of opacity, you generally do not need to write special-purpose code to optimize redrawing. Сравните это с программированием для Win32, в котором можно потратить значительные усилия на оптимизацию приложения, уменьшая объем перерисовки в области обновления.Compare this with Win32 programming in which you can spend a great deal of effort in optimizing your application by minimizing the amount of redrawing in the update region. Пример сложного случая оптимизации перерисовки для приложений Win32 см. в разделе Перерисовка в области обновления.See Redrawing in the Update Region for an example of the type of complexity involved in optimizing redrawing in Win32 applications.

Векторная графикаVector Graphics

WPFWPF использует векторную графику качестве формата данных отрисовки.uses vector graphics as its rendering data format. Векторная графика, к которой относятся масштабируемые векторные рисунки (SVG), метафайлы Windows (WMF) и шрифты TrueType, хранит данные отрисовки и передает их в виде списка инструкций, которые описывают, как воссоздать изображение с помощью графических примитивов.Vector graphics—which include Scalable Vector Graphics (SVG), Windows metafiles (.wmf), and TrueType fonts—store rendering data and transmit it as a list of instructions that describe how to recreate an image using graphics primitives. Например, шрифты TrueType — это контурные шрифты, которые описывают набор линий, кривых и команд, а не массив точек.For example, TrueType fonts are outline fonts that describe a set of lines, curves, and commands, rather than an array of pixels. Одним из основных преимуществ векторной графики является возможность масштабирования до любого размера и разрешения.One of the key benefits of vector graphics is the ability to scale to any size and resolution.

В отличие от векторной графики в растровой графике данные отрисовки представлены в попиксельном виде для определенного разрешения.Unlike vector graphics, bitmap graphics store rendering data as a pixel-by-pixel representation of an image, pre-rendered for a specific resolution. Одним из ключевых различий между растровой и векторной графикой является соответствие исходному изображению.One of the key differences between bitmap and vector graphic formats is fidelity to the original source image. Например, при изменении размера исходного изображения в растровой графике изображение растягивается, тогда как в векторной — масштабируется с сохранением качества.For example, when the size of a source image is modified, bitmap graphics systems stretch the image, whereas vector graphics systems scale the image, preserving the image fidelity.

На следующем рисунке показано исходное изображение, которое было увеличено в 3 раза (масштаб 300 %).The following illustration shows a source image that has been resized by 300%. Обратите внимание на искажения, которые появляются при растяжении исходного изображения в растровом формате по сравнению с векторным.Notice the distortions that appear when the source image is stretched as a bitmap graphics image rather than scaled as a vector graphics image.

Различия между растровой и векторной графикой

В следующем примере показано определение двух элементов Path.The following markup shows two Path elements defined. Во втором элементе с помощью ScaleTransform к инструкциям отрисовки первого элемента применяется операция изменения размера на 300 %.The second element uses a ScaleTransform to resize the drawing instructions of the first element by 300%. Обратите внимание, что инструкции отрисовки в элементе Path остаются без изменений.Notice that the drawing instructions in the Path elements remain unchanged.

<Path
  Data="M10,100 C 60,0 100,200 150,100 z"
  Fill="{StaticResource linearGradientBackground}"
  Stroke="Black"
  StrokeThickness="2" />

<Path
  Data="M10,100 C 60,0 100,200 150,100 z"
  Fill="{StaticResource linearGradientBackground}"
  Stroke="Black"
  StrokeThickness="2" >
  <Path.RenderTransform>
    <ScaleTransform ScaleX="3.0" ScaleY="3.0" />
  </Path.RenderTransform>
</Path>

О разрешении и аппаратно независимой графикеAbout Resolution and Device-Independent Graphics

Существуют два фактора, которые определяют размер текста и графики на экране: разрешение и количество точек на дюйм.There are two system factors that determine the size of text and graphics on your screen: resolution and DPI. Разрешение определяет число пикселей, отображаемых на экране.Resolution describes the number of pixels that appear on the screen. Чем выше разрешение, тем меньше размер пикселей и тем меньше отображаемые объекты и текст.As the resolution gets higher, pixels get smaller, causing graphics and text to appear smaller. Изображение на мониторе с разрешением 1024 x 768 значительно уменьшится, если изменить разрешение на 1600 x 1200.A graphic displayed on a monitor set to 1024 x 768 will appear much smaller when the resolution is changed to 1600 x 1200.

Другой системный параметр, количество точек на дюйм, описывает размер дюйма экрана в пикселях.The other system setting, DPI, describes the size of a screen inch in pixels. В большинстве систем Windows используется значение DPI 96, означающее, что экранный дюйм составляет 96 пикселей.Most Windows systems have a DPI of 96, which means a screen inch is 96 pixels. При повышении количества точек на дюйм экранный дюйм увеличивается, при понижении — уменьшается.Increasing the DPI setting makes the screen inch larger; decreasing the DPI makes the screen inch smaller. Это означает, что дюйм экрана не совпадает с размером настоящего дюйма, по крайней мере в большинстве систем.This means that a screen inch isn't the same size as a real-world inch; on most systems, it's probably not. При увеличении количества точек на дюйм изображения и текст становятся больше, так как увеличивается размер экранного дюйма.As you increase the DPI, DPI-aware graphics and text become larger because you've increased the size of the screen inch. Увеличение количества точек на дюйм может сделать текст более удобным для чтения, особенно при высоких разрешениях.Increasing the DPI can make text easier to read, especially at high resolutions.

Не все приложения поддерживают количество точек на дюйм: в некоторых приложениях в качестве основной единицы измерения используются аппаратно зависимые пиксели, и изменение количества точек на дюйм не влияет на такие приложения.Not all applications are DPI-aware: some use hardware pixels as the primary unit of measurement; changing the system DPI has no effect on these applications. Во многих других приложениях количество точек на дюйм используется при описании размеров шрифта, но для остальных элементов используются пиксели.Many other applications use DPI-aware units to describe font sizes, but use pixels to describe everything else. Слишком маленькое или слишком большое количество точек на дюйм может вызвать проблемы с разметкой для этих приложений, так как размер текста приложения будет изменяться с изменением системного количества точек на дюйм, тогда как интерфейс приложения изменяться не будет.Making the DPI too small or too large can cause layout problems for these applications, because the applications' text scales with the system's DPI setting, but the applications' UI does not. Для приложений, разработанных с помощью WPFWPF, эта проблема устранена.This problem has been eliminated for applications developed using WPFWPF.

WPFWPF поддерживает автоматическое масштабирование с помощью аппаратно независимых пикселей вместо аппаратно зависимых пикселей; изображения и текст масштабируются правильно без дополнительных действий со стороны разработчика приложения.supports automatic scaling by using the device independent pixel as its primary unit of measurement, instead of hardware pixels; graphics and text scale properly without any extra work from the application developer. На следующем рисунке показан пример отображения текста и графики WPFWPF с различными параметрами количества точек на дюйм.The following illustration shows an example of how WPFWPF text and graphics are appear at different DPI settings.

Графика и текст с различными параметрами dpiGraphics and text at different DPI settings
Изображения и текст с различными параметрами количества точек на дюймGraphics and text at different DPI settings

Класс VisualTreeHelperVisualTreeHelper Class

Класс VisualTreeHelper — это статический вспомогательный класс, предоставляющий низкоуровневые функции для программирования на уровне визуального объекта, что полезно в определенных случаях, например при разработке пользовательских элементов управления высокой производительности.The VisualTreeHelper class is a static helper class that provides low-level functionality for programming at the visual object level, which is useful in very specific scenarios, such as developing high-performance custom controls. В большинстве случаев высокоуровневые объекты WPFWPF, например Canvas и TextBlock, обладают большей гибкостью и простотой использования.In most case, the higher-level WPFWPF framework objects, such as Canvas and TextBlock, offer greater flexibility and ease of use.

Проверка нажатияHit Testing

Класс VisualTreeHelper предоставляет методы проверки нажатия визуальных объектов, если поддержка проверки нажатия по умолчанию не соответствует вашим потребностям.The VisualTreeHelper class provides methods for hit testing on visual objects when the default hit test support does not meet your needs. Можно использовать методы HitTest класса VisualTreeHelper, чтобы определить, находится ли геометрический объект или значение координат точки в пределах границ заданного объекта, например элемента управления или графического элемента.You can use the HitTest methods in the VisualTreeHelper class to determine whether a geometry or point coordinate value is within the boundary of a given object, such as a control or graphic element. Например, с помощью проверки нажатия можно определить, попадает ли щелчок мыши в пределах ограничивающего прямоугольника объекта в окружность. Также можно переопределить реализацию проверки нажатия по умолчанию и выполнять собственные вычисления для проверки нажатия.For example, you could use hit testing to determine whether a mouse click within the bounding rectangle of an object falls within the geometry of a circle You can also choose to override the default implementation of hit testing to perform your own custom hit test calculations.

Дополнительные сведения о проверке нажатия см. в разделе Проверка нажатия на визуальном уровне.For more information on hit testing, see Hit Testing in the Visual Layer.

Перечисление визуального дереваEnumerating the Visual Tree

Класс VisualTreeHelper предоставляет функциональные возможности для перечисления элементов визуального дерева.The VisualTreeHelper class provides functionality for enumerating the members of a visual tree. Чтобы извлечь родительский объект, вызовите метод GetParent.To retrieve a parent, call the GetParent method. Чтобы получить дочерний элемент или прямого потомка визуального объекта, вызовите метод GetChild.To retrieve a child, or direct descendant, of a visual object, call the GetChild method. Этот метод возвращает дочерний Visual элемент родителя по указанному индексу.This method returns a child Visual of the parent at the specified index.

В следующем примере показано, как перечислить всех потомков визуального объекта. Этот метод можно использовать для сериализации всех данных отрисовки в иерархии визуального объекта.The following example shows how to enumerate all the descendants of a visual object, which is a technique you might want to use if you were interested in serializing all the rendering information of a visual object hierarchy.

// Enumerate all the descendants of the visual object.
static public void EnumVisual(Visual myVisual)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
    {
        // Retrieve child visual at specified index value.
        Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i);

        // Do processing of the child visual object.

        // Enumerate children of the child visual object.
        EnumVisual(childVisual);
    }
}
' Enumerate all the descendants of the visual object.
Public Shared Sub EnumVisual(ByVal myVisual As Visual)
    For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(myVisual) - 1
        ' Retrieve child visual at specified index value.
        Dim childVisual As Visual = CType(VisualTreeHelper.GetChild(myVisual, i), Visual)

        ' Do processing of the child visual object.

        ' Enumerate children of the child visual object.
        EnumVisual(childVisual)
    Next i
End Sub

В большинстве случаев логическое дерево более удобно для представления элементов приложения WPFWPF.In most cases, the logical tree is a more useful representation of the elements in a WPFWPF application. Хотя логическое дерево нельзя изменить напрямую, с помощью этой схемы удобно представить наследование свойств и маршрутизацию событий.Although you do not modify the logical tree directly, this view of the application is useful for understanding property inheritance and event routing. В отличие от визуального дерева, логическое дерево может представлять и невизуальные объекты, например ListItem.Unlike the visual tree, the logical tree can represent non-visual data objects, such as ListItem. Дополнительные сведения о логическом дереве см. в разделе Деревья в WPF.For more information on the logical tree, see Trees in WPF.

Класс VisualTreeHelper предоставляет методы для получения ограничивающего прямоугольника визуальных объектов.The VisualTreeHelper class provides methods for returning the bounding rectangle of visual objects. Ограничивающий прямоугольник визуального объекта возвращается методом GetContentBounds.You can return the bounding rectangle of a visual object by calling GetContentBounds. Ограничивающий прямоугольник всех потомков визуального объекта, включая сам визуальный объект, возвращается методом GetDescendantBounds.You can return the bounding rectangle of all the descendants of a visual object, including the visual object itself, by calling GetDescendantBounds. В следующем коде показано, как вычислить ограничивающий прямоугольник для визуального объекта и всех его потомков.The following code shows how you would calculate the bounding rectangle of a visual object and all its descendants.

// Return the bounding rectangle of the parent visual object and all of its descendants.
Rect rectBounds = VisualTreeHelper.GetDescendantBounds(parentVisual);
' Return the bounding rectangle of the parent visual object and all of its descendants.
Dim rectBounds As Rect = VisualTreeHelper.GetDescendantBounds(parentVisual)

См. такжеSee also