Отрисовка элементов управления Windows FormsRendering a Windows Forms Control

Отрисовка обозначает процесс создания визуального представления на экране пользователя.Rendering refers to the process of creating a visual representation on a user's screen. Для отрисовки Windows Forms использует GDI (Новая библиотека графики Windows).Windows Forms uses GDI (the new Windows graphics library) for rendering. Управляемые классы, предоставляющие доступ к GDI, находятся в System.Drawing пространстве имен и его подпространствах имен.The managed classes that provide access to GDI are in the System.Drawing namespace and its subnamespaces.

При отрисовке элемента управления участвуют следующие элементы:The following elements are involved in control rendering:

  • Функциональные возможности рисования, предоставляемые базовым System.Windows.Forms.Controlклассом.The drawing functionality provided by the base class System.Windows.Forms.Control.

  • Неотъемлемые элементы библиотеки графических интерфейсов GDI.The essential elements of the GDI graphics library.

  • Геометрия области рисования.The geometry of the drawing region.

  • Процедура высвобождения графических ресурсов.The procedure for freeing graphics resources.

Функциональные возможности рисования, предоставляемые элементом управленияDrawing Functionality Provided by Control

Базовый класс Control предоставляет функциональные возможности рисования через его Paint событие.The base class Control provides drawing functionality through its Paint event. Элемент управления вызывает событие Paint каждый раз, когда ему требуется обновить его отображение.A control raises the Paint event whenever it needs to update its display. Дополнительные сведения о событиях в .NET Framework см. в разделе обработка и вызов событий.For more information about events in the .NET Framework, see Handling and Raising Events.

Класс данных событий для Paint события, PaintEventArgsсодержит данные, необходимые для рисования элемента управления — маркер графического объекта и прямоугольника, представляющий регион для рисования.The event data class for the Paint event, PaintEventArgs, holds the data needed for drawing a control — a handle to a graphics object and a rectangle object that represents the region to draw in. Эти объекты показаны жирным шрифтом в следующем фрагменте кода.These objects are shown in bold in the following code fragment.

Public Class PaintEventArgs  
   Inherits EventArgs  
   Implements IDisposable  
  
   Public ReadOnly Property ClipRectangle() As System.Drawing.Rectangle  
      ...  
   End Property  
  
   Public ReadOnly Property Graphics() As System.Drawing.Graphics  
      ...  
   End Property  
   ' Other properties and methods.  
   ...  
End Class  
public class PaintEventArgs : EventArgs, IDisposable {  
public System.Drawing.Rectangle ClipRectangle {get;}  
public System.Drawing.Graphics Graphics {get;}  
// Other properties and methods.  
...  
}  

Graphics— Это управляемый класс, который инкапсулирует функциональные возможности рисования, как описано в разделе о GDI далее в этой статье.Graphics is a managed class that encapsulates drawing functionality, as described in the discussion of GDI later in this topic. Является экземпляром Rectangle структуры и определяет доступную область, в которой может нарисоваться элемент управления. ClipRectangleThe ClipRectangle is an instance of the Rectangle structure and defines the available area in which a control can draw. Разработчик элемента управления может вычислить ClipRectangle значение ClipRectangle с помощью свойства элемента управления, как описано в обсуждении геометрии далее в этом разделе.A control developer can compute the ClipRectangle using the ClipRectangle property of a control, as described in the discussion of geometry later in this topic.

Элемент управления должен предоставлять логику отрисовки путем переопределения OnPaint метода, от Controlкоторого он наследуется.A control must provide rendering logic by overriding the OnPaint method that it inherits from Control. OnPaintПолучает доступ к графическому объекту и прямоугольнику для рисования с помощью Graphics ClipRectangle и свойств экземпляра, PaintEventArgs переданного в него.OnPaint gets access to a graphics object and a rectangle to draw in through the Graphics and the ClipRectangle properties of the PaintEventArgs instance passed to it.

Protected Overridable Sub OnPaint(pe As PaintEventArgs)  
protected virtual void OnPaint(PaintEventArgs pe);  

Метод базового Control класса не реализует какие бы то ни было функции рисования Paint , но вызывает делегаты событий, зарегистрированные в событии. OnPaintThe OnPaint method of the base Control class does not implement any drawing functionality but merely invokes the event delegates that are registered with the Paint event. При переопределении OnPaintследует, как правило, OnPaint вызывать метод базового класса Paint , чтобы зарегистрированные делегаты получили событие.When you override OnPaint, you should typically invoke the OnPaint method of the base class so that registered delegates receive the Paint event. Однако элементы управления, которые закрашены всю поверхность, не должны вызывать базовый OnPaintкласс, так как это приводит к мерцанию.However, controls that paint their entire surface should not invoke the base class's OnPaint, as this introduces flicker. Пример переопределения OnPaint события см. в разделе как Создайте элемент управления Windows Forms, отображающийход выполнения.For an example of overriding the OnPaint event, see the How to: Create a Windows Forms Control That Shows Progress.

Примечание

Не вызывайте OnPaint непосредственно из элемента управления; вместо этого Invalidate вызовите метод (наследуется от Control Invalidate) или другой метод, который вызывает.Do not invoke OnPaint directly from your control; instead, invoke the Invalidate method (inherited from Control) or some other method that invokes Invalidate. Метод Invalidate , в свою очередь, OnPaintвызывает.The Invalidate method in turn invokes OnPaint. Метод перегружен, и, в зависимости от аргументов Invalidate e, перерисовок, элемент управления перерисовывает часть его экранной области. InvalidateThe Invalidate method is overloaded, and, depending on the arguments supplied to Invalidate e, a control redraws either some or all of its screen area.

Базовый Control класс определяет другой метод, который удобен для рисования OnPaintBackground — метод.The base Control class defines another method that is useful for drawing — the OnPaintBackground method.

Protected Overridable Sub OnPaintBackground(pevent As PaintEventArgs)  
protected virtual void OnPaintBackground(PaintEventArgs pevent);  

OnPaintBackgroundЗакрашивает фон (и, таким образом, форму) окна и гарантированно ускоряется, при OnPaint этом данные записываются быстрее, поскольку отдельные запросы на рисование объединяются в одно Paint событие, охватывающее все области, которые должны быть перерисовке.OnPaintBackground paints the background (and thereby the shape) of the window and is guaranteed to be fast, while OnPaint paints the details and might be slower because individual paint requests are combined into one Paint event that covers all areas that have to be redrawn. Например, вы можете вызвать метод OnPaintBackground if, если нужно нарисовать градиентный цвет фона для элемента управления.You might want to invoke the OnPaintBackground if, for instance, you want to draw a gradient-colored background for your control.

Хотя OnPaintBackground имеет элемент, подобный событиям, и принимает тот же аргумент OnPaint , что OnPaintBackground и метод, не является истинным методом события.While OnPaintBackground has an event-like nomenclature and takes the same argument as the OnPaint method, OnPaintBackground is not a true event method. PaintBackground События иOnPaintBackground не вызывают делегаты событий.There is no PaintBackground event and OnPaintBackground does not invoke event delegates. При переопределении OnPaintBackground метода производный класс не требуется для OnPaintBackground вызова метода своего базового класса.When overriding the OnPaintBackground method, a derived class is not required to invoke the OnPaintBackground method of its base class.

Основы GDI+GDI+ Basics

Graphics Класс предоставляет методы для рисования различных фигур, таких как круги, треугольники, дуги и эллипсы, а также методы для отображения текста.The Graphics class provides methods for drawing various shapes such as circles, triangles, arcs, and ellipses, as well as methods for displaying text. System.Drawing Пространство имен и его подпространства имен содержат классы, инкапсулирующие графические элементы, такие как фигуры (круги, прямоугольники, дуги и др.), цвета, шрифты, кисти и т. д.The System.Drawing namespace and its subnamespaces contain classes that encapsulate graphics elements such as shapes (circles, rectangles, arcs, and others), colors, fonts, brushes, and so on. Дополнительные сведения о GDI см. в разделе Использование управляемых графических классов.For more information about GDI, see Using Managed Graphics Classes. Основные сведения о GDI также описаны в разделе как: Создайте элемент управления Windows Forms, отображающийход выполнения.The essentials of GDI are also described in the How to: Create a Windows Forms Control That Shows Progress.

Геометрия области рисованияGeometry of the Drawing Region

Свойство элемента управления указывает прямоугольную область, доступную для элемента управления на экране пользователя, ClipRectangle а свойство объекта PaintEventArgs — область, которая на самом деле окрашена. ClientRectangleThe ClientRectangle property of a control specifies the rectangular region available to the control on the user's screen, while the ClipRectangle property of PaintEventArgs specifies the area that is actually painted. (Помните, что рисование выполняется в Paint методе события, который PaintEventArgs принимает экземпляр в качестве аргумента).(Remember that painting is done in the Paint event method that takes a PaintEventArgs instance as its argument). Элементу управления может потребоваться закрасить только часть его доступной области, как в случае, когда изменяется небольшой раздел экрана элемента управления.A control might need to paint only a portion of its available area, as is the case when a small section of the control's display changes. В таких ситуациях разработчик элемента управления должен вычислить фактический прямоугольник для рисования и передать Invalidateего в.In those situations, a control developer must compute the actual rectangle to draw in and pass that to Invalidate. Перегруженные Invalidate версии, которые Region Rectangle принимают или в качестве аргумента, PaintEventArgsиспользуют этот аргумент для создания ClipRectangle свойства.The overloaded versions of Invalidate that take a Rectangle or Region as an argument use that argument to generate the ClipRectangle property of PaintEventArgs.

В следующем фрагменте кода показано, FlashTrackBar как пользовательский элемент управления выполняет вычисление прямоугольной области для рисования.The following code fragment shows how the FlashTrackBar custom control computes the rectangular area to draw in. client Переменная обозначает свойство. ClipRectangleThe client variable denotes the ClipRectangle property. Полный пример см. в разделе как Создайте элемент управления Windows Forms, отображающийход выполнения.For a complete sample, see How to: Create a Windows Forms Control That Shows Progress.

Rectangle invalid = new Rectangle(
    client.X + min, 
    client.Y, 
    max - min, 
    client.Height);

Invalidate(invalid);
Dim invalid As Rectangle = New Rectangle( _
    client.X + lmin, _
    client.Y, _
    lmax - lmin, _
    client.Height)

Invalidate(invalid)

Освобождение графических ресурсовFreeing Graphics Resources

Объекты Graphics являются ресурсоемкими, так как они используют системные ресурсы.Graphics objects are expensive because they use system resources. К System.Drawing.Graphics таким объектам относятся экземпляры класса System.Drawing.Brush, а также экземпляры, System.Drawing.Penи другие графические классы.Such objects include instances of the System.Drawing.Graphics class as well as instances of System.Drawing.Brush, System.Drawing.Pen, and other graphics classes. Очень важно создать графический ресурс только в том случае, если он вам нужен, и сразу выпустить его, как только вы завершите его использование.It is important that you create a graphics resource only when you need it and release it soon as you are finished using it. При создании типа, реализующего IDisposable интерфейс, вызовите его Dispose метод, когда завершите работу с ним, чтобы освободить ресурсы.If you create a type that implements the IDisposable interface, call its Dispose method when you are finished with it in order to free resources.

В следующем фрагменте кода показано, FlashTrackBar как пользовательский элемент управления создает и Brush освобождает ресурс.The following code fragment shows how the FlashTrackBar custom control creates and releases a Brush resource. Полный исходный код см. в разделе как Создайте элемент управления Windows Forms, отображающийход выполнения.For the complete source code, see How to: Create a Windows Forms Control That Shows Progress.

private Brush baseBackground = null;
Private baseBackground As Brush
base.OnPaint(e);
if (baseBackground == null) {
    if (showGradient) {
        baseBackground = new LinearGradientBrush(new Point(0, 0),
                                                 new Point(ClientSize.Width, 0),
                                                 StartColor,
                                                 EndColor);
    }
    else if (BackgroundImage != null) {
        baseBackground = new TextureBrush(BackgroundImage);
    }
    else {
        baseBackground = new SolidBrush(BackColor);
    }
}
MyBase.OnPaint(e)

If (baseBackground Is Nothing) Then

    If (myShowGradient) Then
        baseBackground = New LinearGradientBrush(New Point(0, 0), _
                                                 New Point(ClientSize.Width, 0), _
                                                 StartColor, _
                                                 EndColor)
    ElseIf (BackgroundImage IsNot Nothing) Then
        baseBackground = New TextureBrush(BackgroundImage)
    Else
        baseBackground = New SolidBrush(BackColor)
    End If

End If
protected override void OnResize(EventArgs e) {
    base.OnResize(e);
    if (baseBackground != null) {
        baseBackground.Dispose();
        baseBackground = null;
    }
}
Protected Overrides Sub OnResize(ByVal e As EventArgs)
    MyBase.OnResize(e)
    If (baseBackground IsNot Nothing) Then
        baseBackground.Dispose()
        baseBackground = Nothing
    End If
End Sub

См. такжеSee also