使用VB.NET开发定制控件

简介: 正常情况下,在开发.NET Windows应用程序时,我们都会用到System.Windows.Forms名字空间的控件。可供我们使用的控件很多,从Label、TextBox等简单的控件到MonthCalendar、ColorDialog等功能更丰富、更复杂的控件。
正常情况下,在开发.NET Windows应用程序时,我们都会用到System.Windows.Forms名字空间的控件。可供我们使用的控件很多,从Label、TextBox等简单的控件到MonthCalendar、ColorDialog等功能更丰富、更复杂的控件。尽管这些控件对于我们需要开发的大多数Windows应用程序已经足够好了,但有时我们也需要自己开发一些System.Windows.Forms名字空间不包括的控件。本篇文章将讲述如何使用VB.NET创建定制控件,尤其是在需要提供自己的图形用户接口时。
开发定制的控件并不困难。在开发定制控件时,我们可以使用现有的控件,或者对Control或UserControl类进行扩展。结合使用现有的控件使我们减少提供接口的麻烦,扩展Control或UserControl类意味着我们需要覆盖OnPaint方法,自己绘制图形用户接口。本篇文章中,我们由UserControl类派生了一个定制控件,UserControl类本身也是由继承Control类而生成的。因此读者需要对这二个类有一定的了解。
Control类非常重要,因为它是Windows可视化组件的父类,我们开发的定制类将是Control类的一个子类。我们的定制类一般不会直接由Control类派生而成,相反,一般是对UserControl类进行扩展。
Control类
Control类提供向Windows应用程序用户显示信息的类所要求的基本功能,它处理用户通过键盘和鼠标进行的输入,以及消息的分配和安全。更重要的是,Control类定义了控件的范围(位置和大小),尽管它不实现控件的绘制。
Windows表单控件使用了环境属性,因此其子控件的显示与其周围环境相似。缺省情况下,环境属性是由其父控件获得的,如果类没有父控件或者其环境属性没有设置,则控件试图通过Site属性设置环境属性的值。如果控件没有确定位置,不支持环境属性,或者AmbientProperties对象的属性没有设置,控件就会使用缺省值。一般情况下,控件的环境特性表示控件的一个特征,例如BackColor,它会传递给子控件。例如,缺省情况下,Button控件将具有与其父表单控件相同的BackColor环境属性。
许多Control类的属性、方法和事件都会不加变化地传递给子类。
Control类的属性
下面是Control类的一些最重要的属性
BackColor
控件的背景颜色,是由一个System.Drawing.Color对象表示的。我们可以使用如下所示的代码将一个System.Drawing.Color对象赋给该属性:
control.BackColor = System.Drawing.Color.Red
Enabled
一个表示该控件是否可用的布尔型值,缺省情况下其值为True。
Location
控件的左上角在其窗口中的位置,由一个System.Drawing.Point对象表示。
Name
控件的名字。
Parent
返回控件的父控件或容器的引用。例如,在一个表单中添加的控件的父控件就是该表单,下面的代码将Button1控件所在的表单的标题栏改为“Thank you.”:
Button1.Parent.Text = "Thank you."
Size
控件的大小,由System.Drawing.Size对象表示。
Text
与控件相关的字符串。例如,在Label控件中,Text属性就是显示在标签体上的字符串。
Control类的方法
下面是一些Control类最经常使用的方法
BringToFront
如果该控件在其他一些控件下面,完整地显示该控件。换一句话说,这一方法能够显示一个完整的控件。
CreateGraphics
获取控件的System.Drawing.Graphics对象,我们可以在其上利用System.Drawing.Graphics类的各种方法进行显示。例如,下面的代码获取名字为Button1的控件的Graphics图像,然后在按钮上划一条对角的绿线:
Imports System.Drawing
Dim graphics As Graphics = Button1.CreateGraphics
Dim pen As Pen = New Pen(Color.Green)
graphics.DrawLine(pen, 0, 0, _
Button1.Size.Width, Button1.Size.Height)
但是,用这种方法在控件上画图,所画的图像不是“永久”的。当控件或者包含控件的表单被重画时,用这种方式画的图像就会消失。
Focus
将焦点给予该控件,使它成为活动控件
Hide
将控件的Visible属性设置为False,使它不被显示出来。
GetNextControl
按Tab键控制次序返回下一个控件。
OnXXX
触发XXX事件。这里的XXX可以是Click、ControlAdded、ControlRemoved、DoubleClick、DragDrop、DragEnter、DragLeave、DragOver、Enter、GotFocus、KeyDown、KeyPress、KeyUp、LostFocus、MouseDown、MouseEnter、MouseHover、MouseLeave、MouseMove、MouseUp、Move、Paint、Resize和TextChanged。例如,调用控件的OnClick方法就会触发其Click事件。
Show
将控件的Visible属性设置为True,以显示该控件。
UserControl类
UserControl类提供一个可以用来创建其他控件的空控件,它是Control类的一个间接子类。由该控件派生的对象如下所示:
·System.Object
·System.MarshalByRefObject
·System.ComponentModel.Component
·System.Windows.Forms.Control
·System.Windows.Forms.ScrollableControl
·System.Windows.Forms.ContainerControl
·System.Windows.Forms.UserControl
UserControl类从ContainerControl类继承所有的标准位置和与内存处理有关的代码。在用户定制控件中还需要这些代码。
RoundButton控件
有了Control和UserControl这二个类,开发定制的Windows控件就是轻而易举的了。我们的定制类是通过继承UserControl类而生成的,由于UserControl也是由继承Control类而生成的,我们的定制类将会继承Control类的所有有用的方法、属性和事件。例如,由于是继承Control类生成的,我们的定制类会自动地拥有事件处理程序。
在开发定制控件时特别重要的一个问题是如何显示定制控件的用户界面。无论如何组织定制控件,需要注意的是,定制控件有时会重新显示。因此,当定制控件重绘时,必须重新绘制用户界面。考虑到控件每次重绘时,都会调用Control类的OnPaint方法,使用新的绘制定制控件用户界面的OnPaint方法覆盖该方法就能保证定制控件的保持一定的外观。
表1中的代码是一个名称为RoundButton的控件,在图1中,表单上有一个RoundButton定制控件,表2是其代码。我们需要作的工作基本上就是覆盖OnPaint方法。系统向该方法传递一个PaintEventArgs对象,从该方法中我们可以获得控件的System.Drawing.Graphics对象,然后使用它的方法绘制定制控件的用户界面。
表1:RoundButton控件
Imports System.Windows.Forms
Imports System.Drawing
Public Class RoundButton : Inherits UserControl
Public BackgroundColor As Color = Color.Blue
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim graphics As Graphics = e.Graphics
Dim penWidth As Integer = 4
Dim pen As Pen = New Pen(Color.Black, 4)
Dim fontHeight As Integer = 10
Dim font As Font = New Font("Arial", fontHeight)
Dim brush As SolidBrush = New SolidBrush(BackgroundColor)
graphics.FillEllipse(brush, 0, 0, Width, Height)
Dim textBrush As SolidBrush = New SolidBrush(Color.Black)
graphics.DrawEllipse(pen, CInt(penWidth / 2), _
CInt(penWidth / 2), Width - penWidth, Height - penWidth)
graphics.DrawString(Text, font, textBrush, penWidth, _
Height / 2 - fontHeight)
End Sub
End Class
表1中的代码非常地简单,简直令人不能相信。我们的定制类只有一个方法:OnPaint。简单地说,该方法传递一个PaintEventArgs对象,从中我们可以获得System.Drawing.Graphics对象。这一Graphics对象表示我们的定制控件的绘制区,无论在该Graphics对象上绘制什么东西,它都会显示为定制用户控件的界面。
在Windows的编程中,绘制图形时需要用到笔、画笔等对象,要书写文本,就需要字体对象。下面OnPaint方法中的代码创建了一个宽度为4的System.Drawing.Pen对象:
Dim penWidth As Integer = 4
Dim pen As Pen = New Pen(Color.Black, 4)
然后再创建一个高度为10的Arial Font对象:
Dim fontHeight As Integer = 10
Dim font As Font = New Font("Arial", fontHeight)
我们要作的最后一步的准备工作是实例化一个SolidBrush对象,并使其颜色与backgroundColor字段的颜色一致。
Dim brush As SolidBrush = New SolidBrush(backgroundColor)
现在我们就可以来画了。对于控制的底部,我们可以使用Graphics类的FillEllipse方法,圆的高和宽与控件的高和宽是相同的:
graphics.FillEllipse(brush, 0, 0, Width, Height)
然后,我们可以实例化另一个画笔,用来完成对文本的绘制:
Dim textBrush As SolidBrush = New SolidBrush(Color.Black)
至于圆形,我们可以使用Graphics类的DrawEllipse方法:
graphics.DrawEllipse(pen, Cint(penWidth/2), _
CInt(penWidth/2), Width - penWidth, Height - penWidth)
最后,我们使用DrawString方法在Graphics对象上绘制文本内容:
graphics.DrawString(Text, font, textBrush, penWidth, _
Height / 2 - fontHeight)
我们最后得到的RoundButton控件如下图所示

图:picture1

好了,把控件的代码编译为一个.DLL文件,它就可以供我们随时使用了。
表2中的代码是一个调用了RoundButton控件、名称为MyForm的表单。
表2:RoundButton控件的调用
Public Class MyForm
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
Private WithEvents roundButton As RoundButton
Public Sub New()
MyBase.New()
'这个调用是Windows Form Designer所要求的
InitializeComponent()
'在InitializeComponent()调用后,可以添加任意的实例化代码
End Sub
'表单覆盖,整理组件列表
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Windows Form Designer所要求的
Private components As System.ComponentModel.IContainer
'注意:下面的过程是Windows Form Designer所要求的,
'可以使用Windows Form Designer对它进行修改,
'但不要使用软件编辑程序进行修改
Private Sub InitializeComponent()
'
'MyForm
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 273)
Me.Name = "MyForm"
Me.Text = "Using Custom Control"
roundButton = New RoundButton()
AddHandler roundButton.Click, AddressOf roundButton_Click
roundButton.Text = "Click Here!"
roundButton.BackgroundColor = System.Drawing.Color.White
roundButton.Size = New System.Drawing.Size(80, 80)
roundButton.Location = New System.Drawing.Point(100, 30)
Me.Controls.Add(roundButton)
End Sub
#End Region
Private Sub roundButton_Click(ByVal source As Object, ByVal e As EventArgs)
MessageBox.Show("Thank you.")
End Sub
Public Shared Sub Main()
Dim form As MyForm = New MyForm()
Application.Run(form)
End Sub
End Class
在InitializeComponent方法中,表单对一个RoundButton对象进行实例化,并将RoundButton控件的Click事件与事件处理程序roundButton_Click连接起来:
roundButton = New RoundButton()
AddHandler roundButton.Click, AddressOf roundButton_Click
需要注意的是,由于我们没有在RoundButton类中定义任何事件,因此它的事件处理能力是继承Control类而得来的。
我们下一步要作的就是设置RoundButton控件的一些属性了:
roundButton.Text = "Click Here!"
roundButton.BackgroundColor = System.Drawing.Color.White
roundButton.Size = New System.Drawing.Size(80, 80)
roundButton.Location = New System.Drawing.Point(100, 30)
最后,将roundButton控件添加到表单的控件集中:
Me.Controls.Add(roundButton)
当用户点击控件触发Click事件时,Click事件调用roundButton_Click事件处理程序,显示一个消息框:
Private Sub roundButton_Click(ByVal source As Object, _
ByVal e As EventArgs)
MessageBox.Show("Thank you.")
End Sub
结论
在本篇文章中,我们介绍了开发定制控件时需要理解的System.Windows.Forms名字空间中二个重要的类:Control和UserControl。另外,我们还介绍了如何通过直接扩充UserControl类开发自己的定制控件以及如何在Windows表单中使用定制控件。
相关文章
|
10月前
|
人工智能 芯片
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
|
8月前
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
324 0
|
12月前
|
缓存 算法 安全
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
403 12
|
12月前
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
211 9
|
12月前
|
Web App开发 前端开发 调度
一款基于 .NET + Blazor 开发的智能访客管理系统
一款基于 .NET + Blazor 开发的智能访客管理系统
181 8
|
12月前
|
前端开发 JavaScript C#
基于.NET8+Vue3开发的权限管理&个人博客系统
基于.NET8+Vue3开发的权限管理&个人博客系统
189 7
|
12月前
|
网络协议 C#
基于.NET WinForm开发的一款硬件及协议通讯工具
基于.NET WinForm开发的一款硬件及协议通讯工具
141 7
|
12月前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
358 5
|
机器学习/深度学习 人工智能 物联网
.NET 技术:引领未来开发潮流
.NET 技术以其跨平台兼容性、高效的开发体验、强大的性能表现和安全可靠的架构,成为引领未来开发潮流的重要力量。本文深入探讨了 .NET 的核心优势与特点,及其在企业级应用、移动开发、云计算、人工智能等领域的广泛应用,展示了其卓越的应用价值和未来发展前景。
230 5
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
169 4