正常情况下
在开发
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类的属性方法和事件都会不加变化地传递给子类
1Control类的属性
下面是Control类的一些最重要的属性
★ BackColor
控件的背景颜色是由一个SystemDrawingColor对象表示的我们可以使用如下所示的代码将一个SystemDrawingColor对象赋给该属性
controlBackColor = SystemDrawingColorRed
★ Enabled
一个表示该控件是否可用的布尔型值缺省情况下其值为True
★ Location
控件的左上角在其窗口中的位置由一个SystemDrawingPoint对象表示
★ Name
控件的名字
★ Parent
返回控件的父控件或容器的引用例如在一个表单中添加的控件的父控件就是该表单下面的代码将Button控件所在的表单的标题栏改为Thank you
ButtonParentText = Thank you
★ Size
控件的大小由SystemDrawingSize对象表示
★ Text
与控件相关的字符串例如在Label控件中Text属性就是显示在标签体上的字符串
2Control类的方法
下面是一些Control类最经常使用的方法
★ BringToFront
如果该控件在其他一些控件下面完整地显示该控件换一句话说这一方法能够显示一个完整的控件
★ CreateGraphics
获取控件的SystemDrawingGraphics对象我们可以在其上利用SystemDrawingGraphics 类的各种方法进行显示例如下面的代码获取名字为Button的控件的Graphics图像然后在按钮上划一条对角的绿线
Imports SystemDrawing
Dim graphics As Graphics = ButtonCreateGraphics
Dim pen As Pen = New Pen(ColorGreen)
graphicsDrawLine(pen _
ButtonSizeWidth ButtonSizeHeight)
但是用这种方法在控件上画图所画的图像不是永久的当控件或者包含控件的表单被重画时用这种方式画的图像就会消失
★ Focus
将焦点给予该控件使它成为活动控件
★ Hide
将控件的Visible属性设置为False使它不被显示出来
★ GetNextControl
按Tab键控制次序返回下一个控件
★ OnXXX
触发XXX事件这里的XXX可以是ClickControlAddedControlRemovedDoubleClickDragDropDragEnterDragLeaveDragOverEnterGotFocusKeyDownKeyPressKeyUpLostFocusMouseDownMouseEnterMouseHoverMouseLeaveMouseMoveMouseUpMovePaintResize和TextChanged例如调用控件的OnClick方法就会触发其Click事件
★ Show
将控件的Visible属性设置为True以显示该控件
二UserControl类
UserControl类提供一个可以用来创建其他控件的空控件它是Control类的一个间接子类由该控件派生的对象如下所示
·SystemObject
·SystemMarshalByRefObject
·SystemComponentModelComponent
·SystemWindowsFormsControl
·SystemWindowsFormsScrollableControl
·SystemWindowsFormsContainerControl
·SystemWindowsFormsUserControl
UserControl类从ContainerControl类继承所有的标准位置和与内存处理有关的代码在用户定制控件中还需要这些代码
三RoundButton控件
有了Control和UserControl这二个类开发定制的Windows控件就是轻而易举的了我们的定制类是通过继承UserControl类而生成的由于UserControl也是由继承Control类而生成的我们的定制类将会继承Control类的所有有用的方法属性和事件例如由于是继承Control类生成的我们的定制类会自动地拥有事件处理程序
在开发定制控件时特别重要的一个问题是如何显示定制控件的用户界面无论如何组织定制控件需要注意的是定制控件有时会重新显示因此当定制控件重绘时必须重新绘制用户界面考虑到控件每次重绘时都会调用Control类的OnPaint方法使用新的绘制定制控件用户界面的OnPaint方法覆盖该方法就能保证定制控件的保持一定的外观
表中的代码是一个名称为RoundButton的控件在图中表单上有一个RoundButton定制控件表是其代码我们需要作的工作基本上就是覆盖OnPaint方法系统向该方法传递一个PaintEventArgs对象从该方法中我们可以获得控件的SystemDrawingGraphics对象然后使用它的方法绘制定制控件的用户界面
表RoundButton控件
Imports SystemWindowsForms
Imports SystemDrawing
Public Class RoundButton : Inherits UserControl
Public BackgroundColor As Color = ColorBlue
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim graphics As Graphics = eGraphics
Dim penWidth As Integer =
Dim pen As Pen = New Pen(ColorBlack )
Dim fontHeight As Integer =
Dim font As Font = New Font(Arial fontHeight)
Dim brush As SolidBrush = New SolidBrush(BackgroundColor)
graphicsFillEllipse(brush Width Height)
Dim textBrush As SolidBrush = New SolidBrush(ColorBlack)
graphicsDrawEllipse(pen CInt(penWidth / ) _
CInt(penWidth / ) Width penWidth Height penWidth)
graphicsDrawString(Text font textBrush penWidth _
Height / fontHeight)
End Sub
End Class
表中的代码非常地简单简直令人不能相信我们的定制类只有一个方法OnPaint简单地说该方法传递一个PaintEventArgs对象从中我们可以获得SystemDrawingGraphics对象这一Graphics对象表示我们的定制控件的绘制区无论在该Graphics对象上绘制什么东西它都会显示为定制用户控件的界面
在Windows的编程中绘制图形时需要用到笔画笔等对象要书写文本就需要字体对象下面OnPaint方法中的代码创建了一个宽度为的SystemDrawingPen对象
Dim penWidth As Integer =
Dim pen As Pen = New Pen(ColorBlack )
然后再创建一个高度为的Arial Font对象
Dim fontHeight As Integer =
Dim font As Font = New Font(Arial fontHeight)
我们要作的最后一步的准备工作是实例化一个SolidBrush对象并使其颜色与backgroundColor字段的颜色一致
Dim brush As SolidBrush = New SolidBrush(backgroundColor)
现在我们就可以来画了对于控制的底部我们可以使用Graphics类的FillEllipse方法圆的高和宽与控件的高和宽是相同的
graphicsFillEllipse(brush Width Height)
然后我们可以实例化另一个画笔用来完成对文本的绘制
Dim textBrush As SolidBrush = New SolidBrush(ColorBlack)
至于圆形我们可以使用Graphics类的DrawEllipse方法
graphicsDrawEllipse(pen Cint(penWidth/) _
CInt(penWidth/) Width penWidth Height penWidth)
最后我们使用DrawString方法在Graphics对象上绘制文本内容
graphicsDrawString(Text font textBrush penWidth _
Height / fontHeight)
我们最后得到的RoundButton控件如下图所示
图picture
好了把控件的代码编译为一个DLL文件它就可以供我们随时使用了
表中的代码是一个调用了RoundButton控件名称为MyForm的表单
表RoundButton控件的调用
Public Class MyForm
Inherits SystemWindowsFormsForm
#Region Windows Form Designer generated code
Private WithEvents roundButton As RoundButton
Public Sub New()
MyBaseNew()
这个调用是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
componentsDispose()
End If
End If
MyBaseDispose(disposing)
End Sub
Windows Form Designer所要求的
Private components As SystemComponentModelIContainer
注意下面的过程是Windows Form Designer所要求的
可以使用Windows Form Designer对它进行修改
但不要使用软件编辑程序进行修改
Private Sub InitializeComponent()
MyForm
MeAutoScaleBaseSize = New SystemDrawingSize( )
MeClientSize = New SystemDrawingSize( )
MeName = MyForm
MeText = Using Custom Control
roundButton = New RoundButton()
AddHandler roundButtonClick AddressOf roundButton_Click
roundButtonText = Click Here!
roundButtonBackgroundColor = SystemDrawingColorWhite
roundButtonSize = New SystemDrawingSize( )
roundButtonLocation = New SystemDrawingPoint( )
MeControlsAdd(roundButton)
End Sub
#End Region
Private Sub roundButton_Click(ByVal source As Object ByVal e As EventArgs)
MessageBoxShow(Thank you)
End Sub
Public Shared Sub Main()
Dim form As MyForm = New MyForm()
ApplicationRun(form)
End Sub
End Class
在InitializeComponent方法中表单对一个RoundButton对象进行实例化并将RoundButton 控件的Click事件与事件处理程序roundButton_Click连接起来
roundButton = New RoundButton()
AddHandler roundButtonClick AddressOf roundButton_Click
需要注意的是由于我们没有在RoundButton类中定义任何事件因此它的事件处理能力是继承Control类而得来的
我们下一步要作的就是设置RoundButton控件的一些属性了
roundButtonText = Click Here!
roundButtonBackgroundColor = SystemDrawingColorWhite
roundButtonSize = New SystemDrawingSize( )
roundButtonLocation = New SystemDrawingPoint( )
最后将roundButton控件添加到表单的控件集中
MeControlsAdd(roundButton)
当用户点击控件触发Click事件时Click事件调用roundButton_Click事件处理程序显示一个消息框
Private Sub roundButton_Click(ByVal source As Object _
ByVal e As EventArgs)
MessageBoxShow(Thank you)
End Sub
四结论
在本篇文章中我们介绍了开发定制控件时需要理解的SystemWindowsForms名字空间中二个重要的类Control和UserControl另外我们还介绍了如何通过直接扩充UserControl类开发自己的定制控件以及如何在Windows表单中使用定制控件