扩展现有控件

如果要向现有控件添加更多功能,可以创建继承自现有控件的控件。 新控件包含基本控件的所有功能和视觉对象方面,但你也可以对其进行扩展。 例如,如果要创建继承 Button 的控件,则新控件的外观和行为将与按钮完全一样。 可创建新的方法和属性来自定义控件的行为。 某些控件允许替代 OnPaint 方法以更改控件的外观。

将自定义控件添加到项目

创建新项目后,使用 Visual Studio 模板创建用户控件。 以下步骤演示如何将用户控件添加到项目:

  1. 在 Visual Studio 中,找到“项目资源管理器”窗格。 右键单击该项目并选择“添加”>“类”

    右键单击 Visual Studio 解决方案资源管理器,将用户控件添加到 Windows 窗体项目

  2. 在“名称”框中,键入用户控件的名称。 Visual Studio 提供一个可以使用的默认和唯一名称。 接下来,按“添加”

    Visual Studio 中用于为 Windows 窗体添加项的对话框

创建用户控件后,Visual Studio 将打开控件的代码编辑器。 下一步是将此自定义控件转换为按钮并进行扩展。

将自定义控件更改为按钮

在本部分中,你将了解如何将自定义控件更改为可计算并显示单击次数的按钮。

.NET 的 Windows 窗体自定义控件

将自定义控件添加到名为 CustomControl1 的项目后,应打开控件设计器。 如果未打开,请双击解决方案资源管理器中的控件。 按照以下步骤将自定义控件转换为继承自 Button 的控件并对其进行扩展:

  1. 打开控件设计器后,按 F7 或右键单击设计器窗口,然后选择“查看代码”

  2. 在代码编辑器中,应会看到以下类定义:

    namespace CustomControlProject
    {
        public partial class CustomControl2 : Control
        {
            public CustomControl2()
            {
                InitializeComponent();
            }
    
            protected override void OnPaint(PaintEventArgs pe)
            {
                base.OnPaint(pe);
            }
        }
    }
    
    Public Class CustomControl2
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
    
            'Add your custom paint code here
        End Sub
    
    End Class
    
  3. 将基类从 Control 更改为 Button

    重要

    如果使用 Visual Basic,则基类在控件的 *.designer.vb 文件中定义。 在 Visual Basic 中使用的基类为 System.Windows.Forms.Button

  4. 添加名为 _counter 的类范围变量。

    private int _counter = 0;
    
    Private _counter As Integer = 0
    
  5. 重写 OnPaint 方法。 此方法将绘制控件。 控件应绘制按钮顶部的字符串,因此必须先调用基类的 OnPaint 方法,然后绘制字符串。

    protected override void OnPaint(PaintEventArgs pe)
    {
        // Draw the control
        base.OnPaint(pe);
    
        // Paint our string on top of it
        pe.Graphics.DrawString($"Clicked {_counter} times", Font, Brushes.Purple, new PointF(3, 3));
    }
    
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    
        ' Draw the control
        MyBase.OnPaint(e)
    
        ' Paint our string on top of it
        e.Graphics.DrawString($"Clicked {_counter} times", Font, Brushes.Purple, New PointF(3, 3))
    
    End Sub
    
  6. 最后,替代 OnClick 方法。 每次按下控件时都会调用此方法。 此代码将增加计数器的值,然后调用 Invalidate 方法,这会强制控件重新绘制自身。

    protected override void OnClick(EventArgs e)
    {
        // Increase the counter and redraw the control
        _counter++;
        Invalidate();
    
        // Call the base method to invoke the Click event
        base.OnClick(e);
    }
    
    Protected Overrides Sub OnClick(e As EventArgs)
    
        ' Increase the counter and redraw the control
        _counter += 1
        Invalidate()
    
        ' Call the base method to invoke the Click event
        MyBase.OnClick(e)
    
    End Sub
    

    最终代码应类似于以下代码片段:

    public partial class CustomControl1 : Button
    {
        private int _counter = 0;
    
        public CustomControl1()
        {
            InitializeComponent();
        }
    
        protected override void OnPaint(PaintEventArgs pe)
        {
            // Draw the control
            base.OnPaint(pe);
    
            // Paint our string on top of it
            pe.Graphics.DrawString($"Clicked {_counter} times", Font, Brushes.Purple, new PointF(3, 3));
        }
    
        protected override void OnClick(EventArgs e)
        {
            // Increase the counter and redraw the control
            _counter++;
            Invalidate();
    
            // Call the base method to invoke the Click event
            base.OnClick(e);
        }
    }
    
    Public Class CustomControl1
    
        Private _counter As Integer = 0
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    
            ' Draw the control
            MyBase.OnPaint(e)
    
            ' Paint our string on top of it
            e.Graphics.DrawString($"Clicked {_counter} times", Font, Brushes.Purple, New PointF(3, 3))
    
        End Sub
    
        Protected Overrides Sub OnClick(e As EventArgs)
    
            ' Increase the counter and redraw the control
            _counter += 1
            Invalidate()
    
            ' Call the base method to invoke the Click event
            MyBase.OnClick(e)
    
        End Sub
    
    End Class
    

创建控件后,编译项目以使用新控件填充“工具箱”窗口。 打开窗体设计器并将控件拖动到该窗体。 运行项目并按下按钮。 每按一次,单击次数会增加一次。 单击总数将打印为按钮顶部的文本。

用于 Windows 窗体的 Visual Studio 工具箱窗口,其中显示一个自定义控件。