vb.net

位置:IT落伍者 >> vb.net >> 浏览文章

使用VB.NET开发定制控件


发布日期:2021年12月07日
 
使用VB.NET开发定制控件
正常情况下在开发NET Windows应用程序时我们都会用到SystemWindowsForms名字空间的控件可供我们使用的控件很多从LabelTextBox等简单的控件到MonthCalendarColorDialog等功能更丰富更复杂的控件尽管这些控件对于我们需要开发的大多数Windows应用程序已经足够好了但有时我们也需要自己开发一些SystemWindowsForms名字空间不包括的控件本篇文章将讲述如何使用VBNET创建定制控件尤其是在需要提供自己的图形用户接口时

开发定制的控件并不困难在开发定制控件时我们可以使用现有的控件或者对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

控件的背景颜色是由一个SystemDrawingColor对象表示的我们可以使用如下所示的代码将一个SystemDrawingColor对象赋给该属性

controlBackColor = SystemDrawingColorRed

★ Enabled

一个表示该控件是否可用的布尔型值缺省情况下其值为True

★ Location

控件的左上角在其窗口中的位置由一个SystemDrawingPoint对象表示

★ Name

控件的名字

★ Parent

返回控件的父控件或容器的引用例如在一个表单中添加的控件的父控件就是该表单下面的代码将Button控件所在的表单的标题栏改为Thank you

ButtonParentText = Thank you

★ Size

控件的大小由SystemDrawingSize对象表示

★ Text

与控件相关的字符串例如在Label控件中Text属性就是显示在标签体上的字符串

Control类的方法

下面是一些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表单中使用定制控件

上一篇:VB.NET中的多窗体编程:升级到 .NET

下一篇:在VB.NET中进行抓屏