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


Руководство: Разработка простого элемента управления форм Windows Forms

В этом разделе рассматриваются основные этапы разработки пользовательского элемента управления Windows Forms. Простейший элемент управления, разработанный в этом пошаговом руководстве, позволяет изменять выравнивание своего свойства Text. Он не инициирует и не обрабатывает события.

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

  1. Определите класс, унаследованный от класса System.Windows.Forms.Control.

    Public Class FirstControl
       Inherits Control
    
    End Class
    
    public class FirstControl:Control{}
    
  2. Определите свойства. (Это необязательно, т.к. элемент управления наследует многие свойства от класса Control, но для большинства пользовательских элементов управления обычно определяются дополнительные свойства.) В следующем фрагменте кода определяется свойство с именем TextAlignment , которое используется FirstControl для форматирования значения свойства Text, унаследованного от Control. Дополнительные сведения об определении свойств см. в разделе Общие сведения о свойствах.

    ' ContentAlignment is an enumeration defined in the System.Drawing
    ' namespace that specifies the alignment of content on a drawing 
    ' surface.
    Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft
    
    <Category("Alignment"), Description("Specifies the alignment of text.")> _
    Public Property TextAlignment() As ContentAlignment
    
       Get
          Return alignmentValue
       End Get
       Set
          alignmentValue = value
    
          ' The Invalidate method invokes the OnPaint method described 
          ' in step 3.
          Invalidate()
       End Set
    End Property
    
    // ContentAlignment is an enumeration defined in the System.Drawing
    // namespace that specifies the alignment of content on a drawing 
    // surface.
    private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;
    

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

  3. Переопределите защищенный метод OnPaint, наследуемый от Control, чтобы обеспечить логику отрисовки элемента управления. Если не переопределить метод OnPaint, элемент управления не сможет себя нарисовать. В следующем фрагменте кода метод OnPaint отображает значение свойства Text, унаследованного от Control, с выравниванием, определяемым значением поля alignmentValue.

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
    
       MyBase.OnPaint(e)
       Dim style As New StringFormat()
       style.Alignment = StringAlignment.Near
       Select Case alignmentValue
          Case ContentAlignment.MiddleLeft
             style.Alignment = StringAlignment.Near
          Case ContentAlignment.MiddleRight
             style.Alignment = StringAlignment.Far
          Case ContentAlignment.MiddleCenter
             style.Alignment = StringAlignment.Center
       End Select
    
       ' Call the DrawString method of the System.Drawing class to write   
       ' text. Text and ClientRectangle are properties inherited from
       ' Control.
       e.Graphics.DrawString( _
           me.Text, _
           me.Font, _
           New SolidBrush(ForeColor), _
           RectangleF.op_Implicit(ClientRectangle), _
           style)
    
    End Sub
    
    protected override void OnPaint(PaintEventArgs e) 
    {   
        base.OnPaint(e);
        StringFormat style = new StringFormat();
        style.Alignment = StringAlignment.Near;
        switch (alignmentValue) 
        {
            case ContentAlignment.MiddleLeft:
                style.Alignment = StringAlignment.Near;
                break;
            case ContentAlignment.MiddleRight:
                style.Alignment = StringAlignment.Far;
                break;
            case ContentAlignment.MiddleCenter:
                style.Alignment = StringAlignment.Center;
                break;
        }
    
        // Call the DrawString method of the System.Drawing class to write   
        // text. Text and ClientRectangle are properties inherited from
        // Control.
        e.Graphics.DrawString(
            Text, 
            Font, 
            new SolidBrush(ForeColor), 
            ClientRectangle, style);
    
    } 
    
  4. Задайте атрибуты для элемента управления. Атрибуты позволят визуальному конструктору отображать элемент управления и, соответственно, его свойства и события в режиме разработки. Следующий фрагмент кода применяет атрибуты для свойства TextAlignment. В конструкторе, таком как Visual Studio, атрибут Category (показанный во фрагменте кода) позволяет свойству отображаться в соответствующей логической категории. Атрибут Description обеспечивает отображение строки описания внизу окна Свойства, если выбрано свойство TextAlignment. Дополнительные сведения об атрибутах см. в разделе Атрибуты времени разработки для компонентов.

    <Category("Alignment"), Description("Specifies the alignment of text.")> _
    Public Property TextAlignment() As ContentAlignment
    
    [
    Category("Alignment"),
    Description("Specifies the alignment of text.")
    ]
    
  5. Предоставьте ресурсы для элемента управления (необязательное действие). Для элемента управления можно предоставить ресурс, такой как растровый рисунок, используя параметр компилятора (/res для C#), чтобы упаковать ресурсы с элементом управления. Во время выполнения ресурсы могут быть извлечены с помощью методов класса ResourceManager. Дополнительные сведения о создании и использовании ресурсов см. раздел Ресурсы в приложениях.

  6. Выполните компиляцию и развертывание элемента управления. Для компиляции и развертывания элемента управления FirstControl, выполните следующие шаги.

    1. Сохраните код следующего образца в исходном файле (например, FirstControl.cs или FirstControl.vb).

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

      vbc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.vb
      
      csc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.cs
      

      Параметр компилятора /t:library сообщает компилятору, что сборка, создаваемая пользователем, является библиотекой (а не исполняемым файлом). Параметр /out задает путь и имя сборки. Параметр /r задает имена сборок, на которые ссылается код. В этом примере создается закрытая сборка, которую может использовать только приложение пользователя. Следовательно, необходимо сохранить ее в каталоге приложения пользователя. Дополнительные сведения об упаковке и развертывании элемента управления для распределения см. в разделе Развертывание .NET Framework и приложений.

В следующем примере показан код модуля FirstControl. Элемент управления помещается в пространство имен CustomWinControls. Пространство имен обеспечивает логическое группирование связанных типов. Можно создать элемент управления в новом или существующем пространстве имен. В C# объявление using (в Visual Basic — Imports) позволяет получать доступ к типам из пространства имен без использования полного имени типа. В следующем примере объявление using разрешает доступ со стороны кода к классу Control из System.Windows.Forms как просто к Control вместо использования полного имени System.Windows.Forms.Control.

Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms


Public Class FirstControl
   Inherits Control

   Public Sub New()
   End Sub 


   ' ContentAlignment is an enumeration defined in the System.Drawing
   ' namespace that specifies the alignment of content on a drawing 
   ' surface.
   Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft

   <Category("Alignment"), Description("Specifies the alignment of text.")> _
   Public Property TextAlignment() As ContentAlignment

      Get
         Return alignmentValue
      End Get
      Set
         alignmentValue = value

         ' The Invalidate method invokes the OnPaint method described 
         ' in step 3.
         Invalidate()
      End Set
   End Property


   Protected Overrides Sub OnPaint(e As PaintEventArgs)

      MyBase.OnPaint(e)
      Dim style As New StringFormat()
      style.Alignment = StringAlignment.Near
      Select Case alignmentValue
         Case ContentAlignment.MiddleLeft
            style.Alignment = StringAlignment.Near
         Case ContentAlignment.MiddleRight
            style.Alignment = StringAlignment.Far
         Case ContentAlignment.MiddleCenter
            style.Alignment = StringAlignment.Center
      End Select

      ' Call the DrawString method of the System.Drawing class to write   
      ' text. Text and ClientRectangle are properties inherited from
      ' Control.
      e.Graphics.DrawString( _
          me.Text, _
          me.Font, _
          New SolidBrush(ForeColor), _
          RectangleF.op_Implicit(ClientRectangle), _
          style)

   End Sub

End Class
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace CustomWinControls
{
    public class FirstControl : Control
    {

        public FirstControl()
        {

        }

        // ContentAlignment is an enumeration defined in the System.Drawing
        // namespace that specifies the alignment of content on a drawing 
        // surface.
        private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;

        [
        Category("Alignment"),
        Description("Specifies the alignment of text.")
        ]
        public ContentAlignment TextAlignment 
        {

            get 
            {
                return alignmentValue;
            }
            set 
            {
                alignmentValue = value;

                // The Invalidate method invokes the OnPaint method described 
                // in step 3.
                Invalidate(); 
            }
        }


        protected override void OnPaint(PaintEventArgs e) 
        {   
            base.OnPaint(e);
            StringFormat style = new StringFormat();
            style.Alignment = StringAlignment.Near;
            switch (alignmentValue) 
            {
                case ContentAlignment.MiddleLeft:
                    style.Alignment = StringAlignment.Near;
                    break;
                case ContentAlignment.MiddleRight:
                    style.Alignment = StringAlignment.Far;
                    break;
                case ContentAlignment.MiddleCenter:
                    style.Alignment = StringAlignment.Center;
                    break;
            }

            // Call the DrawString method of the System.Drawing class to write   
            // text. Text and ClientRectangle are properties inherited from
            // Control.
            e.Graphics.DrawString(
                Text, 
                Font, 
                new SolidBrush(ForeColor), 
                ClientRectangle, style);

        } 
    }
}

Использование пользовательского элемента управления в форме

В следующем примере рассмотрена простая форма, использующая элемент управления FirstControl. В нем создается три экземпляра FirstControl, все с разными значениями свойства TextAlignment.

Компиляция и запуск примера

  1. Сохраните код из следующего образца в исходном файле (SimpleForm.cs или SimpleForms.vb).

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

    vbc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.vb
    
    csc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.cs
    

    CustomWinControls.dll — сборка, содержащая класс FirstControl. Эта сборка должна находиться в том же каталоге, что и исходный файл для формы, которая к ней обращается (SimpleForm.cs или SimpleForms.vb).

  3. Запустите на выполнение файл SimpleForm.exe с помощью следующей команды.

    SimpleForm
    
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms




Public Class SimpleForm
   Inherits System.Windows.Forms.Form

   Private firstControl1 As FirstControl

   Private components As System.ComponentModel.Container = Nothing


   Public Sub New()
      InitializeComponent()
   End Sub 





   Private Sub InitializeComponent()
      Me.firstControl1 = New FirstControl()
      Me.SuspendLayout()

      ' 
      ' firstControl1
      ' 
      Me.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark
      Me.firstControl1.Location = New System.Drawing.Point(96, 104)
      Me.firstControl1.Name = "firstControl1"
      Me.firstControl1.Size = New System.Drawing.Size(75, 16)
      Me.firstControl1.TabIndex = 0
      Me.firstControl1.Text = "Hello World"
      Me.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter

      ' 
      ' SimpleForm
      ' 
      Me.ClientSize = New System.Drawing.Size(292, 266)
      Me.Controls.Add(firstControl1)
      Me.Name = "SimpleForm"
      Me.Text = "SimpleForm"
      Me.ResumeLayout(False)
   End Sub 


   <STAThread()>  _
   Shared Sub Main()
      Application.Run(New SimpleForm())
   End Sub 
End Class 
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace CustomWinControls
{

    public class SimpleForm : System.Windows.Forms.Form
    {
        private FirstControl firstControl1;

        private System.ComponentModel.Container components = null;

        public SimpleForm()
        {
            InitializeComponent();
        }

        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        private void InitializeComponent()
        {
            this.firstControl1 = new FirstControl();
            this.SuspendLayout();

            // 
            // firstControl1
            // 
            this.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark;
            this.firstControl1.Location = new System.Drawing.Point(96, 104);
            this.firstControl1.Name = "firstControl1";
            this.firstControl1.Size = new System.Drawing.Size(75, 16);
            this.firstControl1.TabIndex = 0;
            this.firstControl1.Text = "Hello World";
            this.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;

            // 
            // SimpleForm
            // 
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.Add(this.firstControl1);
            this.Name = "SimpleForm";
            this.Text = "SimpleForm";
            this.ResumeLayout(false);

        }

        [STAThread]
        static void Main() 
        {
            Application.Run(new SimpleForm());
        }


    }
}

См. также

Основные понятия

События элементов управления Windows Forms

Другие ресурсы

Свойства элементов управления Windows Forms