Поделиться через


Что такое пользовательский элемент управления?

В этой статье рассматриваются настраиваемые элементы управления и описывается, чем они отличаются от пользовательских элементов управления. Пользовательские элементы управления не предоставляют визуальную поверхность проектирования и полагаются на предоставленный пользователем код для своего отображения. Это отличается от пользовательских элементов управления, которые предоставляют область визуального проектирования для группировки нескольких элементов управления в одну единицу повторного использования.

Пользовательские элементы управления используются, когда существующий элемент управления или пользовательский элемент управления не способен обеспечить требуемый пользовательский интерфейс или интерактивность. Они требуют больше усилий от вашей стороны, чтобы полностью реализовать. Обработка клавиатуры и мыши по-прежнему осуществляется с помощью Windows Forms, но реализацию всех остальных действий вам предстоит выполнить самостоятельно. Поверхность проектирования не предоставляется с пользовательским элементом управления, так как все рисование выполняется через код в методе OnPaint. Такие компоненты, как Timer, по-прежнему можно добавлять через невизуальный интерфейс конструктора.

Базовый класс

При создании пользовательского элемента управления можно выбрать один из двух базовых классов:

  • System.Windows.Forms.Control

    Это тот же базовый класс, используемый другими элементами управления Windows Forms. Вы управляете входным и выходным данными элемента управления напрямую.

  • System.Windows.Forms.ScrollableControl

    Некоторые элементы управления Windows Forms используют этот базовый класс. Этот класс расширяется Control путем добавления возможности прокрутки содержимого.

Если вам не требуется прокрутка содержимого пользовательского элемента управления, используйте Control в качестве базового класса.

Унаследованные возможности

Поскольку базовым классом пользовательского элемента управления является Control, вы автоматически наследуете функциональные возможности Windows Forms, общие для всех элементов управления. Ниже приведены некоторые возможности, которые вы получаете с помощью пользовательского элемента управления:

  • Ввод клавиатуры и мыши.
  • Механизмы макета, такие как привязка и закрепление.
  • Поддержка вкладок.
  • Минимальные и максимальные ограничения размера.

Живопись

Отрисовка, то есть создание визуальной части элемента управления, осуществляется путем переопределения метода OnPaint. Дополнительные сведения о том, как элементы управления рисуют, см. в статье Рисование и черчение на элементах управления.

При создании пользовательского элемента управления с помощью шаблонов Visual Studio метод OnPaint автоматически переопределяется. Шаблон делает это потому, что вы должны написать код для прорисовки вашего элемента управления. Вот пример того, что генерирует шаблон:

public partial class CustomControl1 : Control
{
    public CustomControl1()
    {
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }
}
Public Class CustomControl1

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        'Add your custom paint code here
    End Sub

End Class

Пользовательский элемент управления окрашивается с помощью метода OnPaint. Единственным аргументом этого метода является объект PaintEventArgs, предоставляющий всю информацию и функциональность, необходимые для отображения элемента управления. PaintEventArgs предоставляет два свойства, которые используются при визуализации элемента управления.

  • PaintEventArgs.ClipRectangle— представляет часть элемента управления, который необходимо перерисовать. Это может быть весь элемент управления или часть элемента управления.

  • Graphics— представляет графическую поверхность элемента управления. Он предоставляет несколько графических объектов и методов, которые обеспечивают функции, необходимые для отрисовки элемента управления.

Метод OnPaint вызывается всякий раз, когда элемент управления рисуется или обновляется на экране, а PaintEventArgs.ClipRectangle объект представляет прямоугольник, в котором выполняется рисование. Если весь элемент управления необходимо обновить, PaintEventArgs.ClipRectangle представляет размер всего элемента управления. Если требуется обновить только часть элемента управления, это представляет собой только область, которую необходимо перерисовать. Пример такого случая заключается в том, что элемент управления частично скрыт другим элементом управления в пользовательском интерфейсе, и когда другой элемент управления двигается в сторону, вновь предоставленная часть элемента управления под ним должна быть перерисована.

Код в OnPaint методе элемента управления запускается при первом рисовании элемента управления и всякий раз, когда он становится недействительным. Чтобы убедиться, что элемент управления перерисовывается при каждом изменении его размера, добавьте следующую строку в конструктор элемента управления:

SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.ResizeRedraw, True)

Пример

Следующий фрагмент кода — это пользовательский элемент управления, который отображает несколько цветных прямоугольников вокруг края элемента управления.

protected override void OnPaint(PaintEventArgs pe)
{
    Rectangle rect = this.ClientRectangle;

    // Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
    // Otherwise, it kind of overlaps the outside edge.
    rect.Width -= 1;
    rect.Height -= 1;

    Pen[] colorPens = new Pen[] { Pens.Blue, Pens.BlueViolet,
                                  Pens.AliceBlue, Pens.CornflowerBlue,
                                  Pens.Cyan, Pens.DarkCyan };

    foreach (Pen pen in colorPens)
    {
        pe.Graphics.DrawRectangle(pen, rect);
        rect.Inflate(-1, -1);
    }

    // Raise the Paint event so users can custom paint if they want.
    base.OnPaint(pe);
}
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

    Dim rect As Rectangle = Me.ClientRectangle

    'Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
    'Otherwise, it kind of overlaps the outside edge.
    rect.Width -= 1
    rect.Height -= 1

    Dim colorPens As Pen() = {Pens.Blue, Pens.BlueViolet,
                                Pens.AliceBlue, Pens.CornflowerBlue,
                                Pens.Cyan, Pens.DarkCyan}

    For Each curPen As Pen In colorPens

        e.Graphics.DrawRectangle(curPen, rect)
        rect.Inflate(-1, -1)

    Next

    'Raise the Paint event so users can custom paint if they want.
    MyBase.OnPaint(e)

End Sub

Предыдущий код создает элемент управления, который выглядит следующим образом:

Пользовательский элемент управления, отрисованный в Visual Studio. Элемент управления является пустым полем с различными цветами, границами. Каждый цвет задается по одному пикселю.

Предыстория

Обратите внимание, что фон элемента управления окрашен цветом SystemColors.Control, даже если код OnPaint не очищает элемент управления и не заполняет его цветом. Фон фактически окрашивается методом OnPaintBackground(PaintEventArgs) перед вызовом OnPaint. Переопределите OnPaintBackground для обработки рисования фона элемента управления. Реализация этого метода по умолчанию заключается в рисовании цвета и изображения, установленными соответственно свойствами BackColor и BackgroundImage.