一步一步创建VisualBasic.NET控件

时间:2007-06-15 来源: 作者: 【字体: 减小 增大收藏 | 投稿
  
摘要:本月BillyHollis将向您介绍如何从头创建可呈现其特有界面的可视控件。

财管家园,fs119.net

  我从来没有真正想过要当一名C程序员,因为我太懒了,不能那么辛苦地工作。但我必须承认,我过去常常嫉妒那些C程序员,嫉妒他们编写可视控件的能力。

  VisualBasic®6.0及其早期版本中的控件仅限于“复合”控件(由其他控件组成的控件),这种控件称为UserControl。在VisualBasic6.0中编写能够在屏幕上呈现其特有可视外观的控件几乎是不可能的。 财管家园 fs119.net

  现在好了,可以使用功能强大的VisualBasic.NET编写各种类型的可视控件了!不仅可以编写复合的UserControl,还能继承现有的控件(如TextBox)并扩展其新功能。更重要的是,还可以从头编写能够呈现其特有界面的可视控件。 财.管家园.fs119.net

  在本文中,我将从头创建一个完整的可视控件,以说明VisualBasic.NET的后一种功能。该控件是一个“红绿灯”-一个包含三个圆(分别代表红、黄、绿三个灯)的矩形。图1显示各个灯亮时该控件的外观,控件的背景颜色设置为系统颜色ControlDark

财软联.盟.fs119.net

财,软联盟,fs119.net

  图1:带有三个TrafficLight控件的窗体,每个控件亮不同的灯。 财管家园.fs119.net

  我们称它为TrafficLight控件,它可以通过代码或让用户单击灯来改变亮起的灯。

财软联盟 fs119.net

  因为TrafficLight是一个可视的Windows窗体控件,它将继承S  ystem.Windows.Forms命名空间中的Control类。这样,它将具有很多预定义的属性、方法和事件,包括控制其外观的属性,如ForeColorBackColorSizeLocation;还包括事件,如MouseOverClick。您可以查看.NET文档,获得Control类成员的完整列表。 财管家园.fs119.net

  红绿灯也需要具有特殊的属性和事件,如下所示: 财管家.园.fs119.net

Status属性 确定亮起哪种颜色的灯。必须为以下三个枚举值之一:
  • StatusRed:红灯亮
  • StatusYellow:黄灯亮
  • StatusGreen:绿灯亮
  • BorderWidth属性 红绿灯周围边框的宽度。 StatusChanged事件 当通过代码或由用户单击不同的灯改变Status属性的值时,触发该事件。

      由于这些成员不属于Control基类,所以我们需要包括完整的代码以处理它们。我们还需要绘制边框和三个相应颜色的灯的代码,以便在屏幕上绘制红绿灯。最后,我们需要处理用户单击圆以更改亮起灯的操作,并在更改亮起的灯时更改Status属性。 财软联 盟 fs119.net

      为了使本示例尽可能接近实际应用环境,我们还将包括能够确保在VisualStudio®.NETIDE中更好地使用控件的代码。我们为工具箱设置适当的图标,并包括能够使属性更好地与各属性窗口集成的逻辑。 财 软联盟 fs119.net

      现在让我们开始吧。 财管,家园,fs119.net

    财管家园 fs119.net

      第1步:创建类型正确的项目 财软 联盟 fs119.net

      要创建一个保存Windows窗体控件的库,需要在VisualBasic.NET中启动一个新项目,选择WindowsControlLibrary(Windows控件库)项目类型,然后将项目命名为MyControls

    财管.家园.fs119.net

      所创建的项目实际上可以保存多个Windows窗体控件,每个控件都属于其各自的类,但我们只需在其中创建一个控件。

    财.软联盟.fs119.net

    财软联盟 fs119.net

    财软联盟,fs119.net


    财管家,园,fs119.net

    财软联 盟 fs119.net

    财软联盟 fs119.net

      第2步:更改基类

    财软 联盟 fs119.net

      在控件库中创建的类自动命名为UserControl1,默认情况下,从UserControl类继承。如果我们要创建复合控件,那非常容易,只需将其他控件从工具箱中拖到设计表面上即可。

    财管家.园.fs119.net

      但是,由于我们要从头创建自己的控件,因此需要做一些更改。将控件类的名称从UserControl1更改为TrafficLight。然后,将以下行:

    财管家园.fs119.net

      InheritsSystem.Windows.Forms.UserControl

    财软联盟,fs119.net

      更改为:

    财管,家园,fs119.net

      InheritsSystem.Windows.Forms.Control

    财管 家园 fs119.net

      这样,使最一般的Control类成为基类。您会发现,不再显示可视设计表面,而是替换为组件设计表面。 财,管家园,fs119.net

      为保持代码的一致性,也要将代码文件名从UserControl1.vb更改为TrafficLight.vb。可以在SolutionExplorer(解决方案资源管理器)中进行更改:右键单击代码文件的名称,并选择Rename(重命名)。 财软联盟.fs119.net

      还需要在类模块的顶部添加几行代码。将OptionStrict设置为On,并导入包含我们将来要用到的某些属性的命名空间。下面是要放到代码最上面的两行:OptionStrictOn
    ImportsSystem.ComponentModel 财 软联盟 fs119.net

      第3步:实现属性和事件

    财管家园.fs119.net

      要实现Status属性,首先要为可能的属性值创建枚举。将以下几行插入以Inherits开始的行下面:

    财软联盟,fs119.net

    PublicEnumTrafficLightStatus
    statusRed=1
    statusYellow=2
    statusGreen=3
    EndEnum

    财软联 盟 fs119.net

      此枚举是公开的,也就是说使用该控件的窗体可以访问它。

    财 软联盟 fs119.net

      在这些行下面添加以下三行: 财管家,园,fs119.net

    DimmStatusAsTrafficLightStatus=TrafficLightStatus.statusGreen
    DimmsngBorderWidthAsSingle=1.0!
    PublicEventStatusChanged(ByValNewStatusAsTrafficLightStatus) 财 软联盟 fs119.net

      前两行中的两个变量可用于存储Status和BorderWidth属性的属性值,还为这些属性设置了默认值。保存BorderWidth的变量必须为Single类型,因为它是绘制边框所用的图形语句需要的类型。默认值中的惊叹号也表明它是Single类型。此集合中的最后一行声明了StatusChanged事件。 财软联.盟.fs119.net

      现在,我们为BorderWidth属性编写代码。在标记为WindowsFormDesignerGeneratedCode(Windows窗体设计器生成的代码)的代码区域下插入以下行: 财,软联盟,fs119.net

    <DefaultValue(1.0!),_
    Description("红绿灯周围边框的宽度")>_
    PublicPropertyBorderWidth()AsSingle
    Get
    ReturnmsngBorderWidth
    EndGet
    Set(ByValValueAsSingle)
    IfmsngBorderWidth<>ValueThen
    msngBorderWidth=Value
    Me.Invalidate()
    EndIf
    EndSet
    EndProperty

    财软.联盟.fs119.net

      前两行包括使该属性更好地使用IDE的属性。DefaultValue特性允许在Properties(属性)窗口中将属性值重置为默认值(操作步骤稍后介绍)。Description特性提供选中该属性时在Properties(属性)窗口底部显示的文本。

    财软联 盟 fs119.net

    财软.联盟.fs119.net

    财管.家园.fs119.net

    财管家,园,fs119.net


    财软联,盟,fs119.net

    财,软联盟,fs119.net

      DefaultValue特性还有一个技巧。如果将TrafficLight控件放到窗体上,并保留BorderWidth属性的默认值,那么窗体设计器将不生成设置属性值的代码行。这使它与其他Windows窗体控件没有什么区别。如果您查看典型控件(如TextBox)的设计器生成的代码,您会发现只包括设置为非默认值的属性的代码行。我们赋予TrafficLight控件同样的能力。

    财管家,园,fs119.net

      PropertyGet简单明了。PropertySet子句包括可视控件属性中常见的逻辑。设置属性时,重要的是在新属性值更改控件的外观时要能够重新绘制控件。因此,Set子句负责确定传递的新值是否与属性中现有的值不相同。如果相同,则不执行操作。如果不同,则接受新值,然后访问控件的Invalidate方法。此方法表明,控件的可视区域已过期,控件需要重新绘制。

    财管 家园 fs119.net

      Status属性的处理有些不同,因为它是枚举值。DefaultValue特性没有为枚举属性提供自动重置能力。在这种情况下,DefaultValue也无法告诉设计器何时停止设置属性值的代码。因此,Status属性的实现中不需要DefaultValue特性。下面是Status属性的代码: 财软联盟.fs119.net

    <Description("红绿灯的状态(颜色)")>_
    PublicPropertyStatus()AsTrafficLightStatus
    Get
    Status=mStatus
    EndGet
    Set(ByValValueAsTrafficLightStatus)
    IfmStatus<>ValueThen
    mStatus=Value
    RaiseEventStatusChanged(mStatus)
    Me.Invalidate()
    EndIf
    EndSet
    EndProperty 财软联盟.fs119.net

      看起来与BorderWidth属性的实现类似,只有一点不同:当Status属性发生改变时,除了强制重新绘制控件外,还会触发StatusChanged事件。 财管家园 fs119.net

      要在Properties(属性)窗口中处理属性的自动重置,我们需要使用一种特殊的方法。由于我们的属性命名为Status,因此必须将重置方法命名为ResetStatus。重置方法只是恢复属性的默认值。以下是其代码:
    财软联盟.fs119.net

    Public

    财软联盟.fs119.net

    SubResetStatus()
    Me.Status=TrafficLightStatus.statusGreen
    EndSub

    财管.家园.fs119.net

    财管家园 fs119.net

      为了提示设计器何时需要包括一行代码以便设置Status属性,我们需要包括一个名为ShouldSerializeStatus的方法。当属性需要一行代码时,此方法返回布尔值True,否则,则返回False。以下是其代码: 财管家园.fs119.net

    PublicFunctionShouldSerializeStatus()AsBoolean
    IfmStatus=TrafficLightStatus.statusGreenThen
    ReturnFalse
    Else
    ReturnTrue
    EndIf
    EndFunction 财软.联盟.fs119.net

      第4步:绘制控件的外观 财软联 盟 fs119.net

    财 管家园 fs119.net

      要使控件具有一个可视的外观,我们需要在Paint事件中放置逻辑。然后,每次控件需要刷新其可视外观时,就会运行该逻辑。 财 管家园 fs119.net

      Windows窗体中的Paint逻辑使用.NET中GDI部分中的类。这些类基本上包括了WindowsAPI图形功能。由于适合.NET,所以比API更易于使用。但是,有关它们的工作原理,需要理解以下几点。 财软联盟,fs119.net

      在WindowsAPI中,图形操作需要一个窗口句柄,有时称为hWnd。在GDI中,它由Graphics对象取代,该对象不仅代表了绘图区域,还提供在该区域执行的操作(方法)。

    财管.家园.fs119.net

      例如,Graphics对象具有以下方法,可用来绘制各种屏幕元素:

    财.管家园.fs119.net

    DrawCurve 财 软联盟 fs119.net

    DrawEllipse

    财管家园 fs119.net

    DrawLine 财软联 盟 fs119.net

    DrawPolygon

    财管家园,fs119.net

    DrawRectangle 财软联 盟 fs119.net

    DrawString 财 软联盟 fs119.net

    FillEllipse 财软联盟,fs119.net

    FillPolygon 财软联.盟.fs119.net

    财,管家园,fs119.net

      这些都是很容易理解的,只是可用方法的示例。一些更复杂的方法还允许旋转对象。我们将使用DrawRectangle方法绘制边框,使用FillEllipse方法绘制彩色的圆。 财软联 盟 fs119.net

    财软联盟 fs119.net

    财 软联盟 fs119.net

    财管.家园.fs119.net


    财管.家园.fs119.net

    财管家 园 fs119.net

      大多数绘图方法都要求使用Pen或Brush对象。Pen对象用于绘制直线并确定直线的颜色和粗细。Brush对象用于填充区域、确定填充区域所使用的颜色,以及一些特殊效果(例如,用位图填充区域)。我们将使用特殊的Brush效果使当前没有亮起的灯的颜色变暗。 财管,家园,fs119.net

      下面是处理控件的Paint事件的代码: 财管家园,fs119.net

    ProtectedOverridesSubOnPaint(ByValpeAs_
    System.Windows.Forms.PaintEventArgs)
    MyBase.OnPaint(pe) 财软.联盟.fs119.net

    DimgrfGraphicsAsSystem.Drawing.Graphics
    grfGraphics=pe.Graphics 财软联 盟 fs119.net

    '首先绘制三个代表灯的圆。
    '一个亮起,其余两个熄灭。
    DrawLight(TrafficLightStatus.statusGreen,grfGraphics)
    DrawLight(TrafficLightStatus.statusYellow,grfGraphics)
    DrawLight(TrafficLightStatus.statusRed,grfGraphics)

    财,管家园,fs119.net

    '现在绘制红绿灯周围的轮廓
    '用画笔绘制轮廓,将它涂成黑色。
    DimpenDrawingPenAsNew_
    System.Drawing.Pen(System.Drawing.Color.Black,msngBorderWidth) 财管家.园.fs119.net

    '在控件上绘制红绿灯的轮廓。
    '首先定义要绘制的矩形。
    DimrectBorderAsSystem.Drawing.Rectangle

    财管家 园 fs119.net

    rectBorder.X=1
    rectBorder.Y=1
    rectBorder.Height=Me.Height-2
    rectBorder.Width=Me.Width-2
    grfGraphics.DrawRectangle(penDrawingPen,rectBorder) 财软,联盟,fs119.net

    '释放图形对象
    penDrawingPen.Dispose()
    grfGraphics.Dispose() 财软联 盟 fs119.net

    EndSub

    财管家园,fs119.net

    财管.家园.fs119.net

      首先使用基类绘制,它通常使用控件的背景颜色绘制背景。然后,从事件参数中获取控件的Graphics对象。 财 管家园 fs119.net

      接下来,用一个函数画出三个圆。有关该函数的内容稍后介绍。请注意,我们必须向该函数传递一个Graphics对象的引用,同时还要指示要画的圆(红、黄、绿)。

    财管家园,fs119.net

      然后是绘制轮廓的代码。声明一个具有适当位置和大小的矩形,然后传递给Graphics对象的DrawRectangle方法。

    财管家 园 fs119.net

      最后,图形对象激活其Dispose方法。使用GDI时,最好在完成图形对象后立即释放它们。这有助于清除操作系统绘图时所用的资源。如果要在Windows®98或WindowsMe中使用控件,管理图形资源就更加重要,因为这些操作系统处理这种资源的能力较差。

    财 管家园 fs119.net

    财管 家园 fs119.net

    财 软联盟 fs119.net


    财软联 盟 fs119.net

    财软联盟,fs119.net

    财管家园.fs119.net

      下面是绘制圆的函数: 财管家园 fs119.net

    PrivateSubDrawLight(ByValLightToDrawAsTrafficLightStatus,_
    ByValgrfGraphicsAsGraphics)

    财管家,园,fs119.net

    DimnCircleXAsInteger
    DimnCircleYAsInteger
    DimnCircleDiameterAsInteger
    DimnCircleColorAsColor 财管家园.fs119.net

    '找到所有圆的X坐标和直径
    nCircleX=CInt(Me.Size.Width*0.02)
    nCircleDiameter=CInt(Me.Size.Width*0.96)
    SelectCaseLightToDraw
    CaseTrafficLightStatus.statusRed
    IfLightToDraw=Me.StatusThen
    nCircleColor=Color.OrangeRed
    Else
    nCircleColor=Color.Maroon
    EndIf
    nCircleY=CInt(Me.Size.Height*0.01)
    CaseTrafficLightStatus.statusYellow
    IfLightToDraw=Me.StatusThen
    nCircleColor=Color.Yellow
    Else
    nCircleColor=Color.Tan
    EndIf
    nCircleY=CInt(Me.Size.Height*0.34)
    CaseTrafficLightStatus.statusGreen
    IfLightToDraw=Me.StatusThen
    nCircleColor=Color.LimeGreen
    Else
    nCircleColor=Color.ForestGreen
    EndIf
    nCircleY=CInt(Me.Size.Height*0.67) 财软.联盟.fs119.net

    EndSelect
    DimbshBrushAsSystem.Drawing.Brush
    IfLightToDraw=Me.StatusThen

    财.管家园.fs119.net

    bshBrush=NewSolidBrush(nCircleColor)
    Else
    bshBrush=NewSolidBrush(Color.FromArgb(60,nCircleColor))
    EndIf 财管家,园,fs119.net

    '绘制代表红绿灯的圆
    grfGraphics.FillEllipse(bshBrush,nCircleX,nCircleY,nCircleDiameter,nCircleDiameter) 财管.家园.fs119.net

    '释放笔刷
    bshBrush.Dispose()

    财管家 园 fs119.net

    EndSub 财管家园 fs119.net

    财软联盟 fs119.net

      这是整个控件中唯一的一个复杂图形。在GDI中,在要绘制椭圆的矩形中指定左上角的X坐标和Y坐标,然后指定矩形的高度和宽度即可绘制一个椭圆。我们分别将X坐标和Y坐标称为nCircleX和nCircleY。因为我们要绘制一个圆,因此矩形的高度等于宽度,用变量nCircleDiameter来控制该值。 财管家园.fs119.net

      将nCircleX设置为刚好放到控件内(控件的宽度乘以0.02)。nCircleY取决于要绘制哪个灯,可以设置成靠近控件的顶部(红灯)、大约向下三分之一(黄灯)或大约向下三分之二(绿灯)。直径nCircleDiameter设置为等于控件宽度的96%。 财软联盟,fs119.net

      要绘制实心椭圆,还需完成一件事,即确定要使用的颜色。颜色取决于正在绘制哪个灯以及正在绘制的灯是否亮起。亮起的灯的颜色要比熄灭的灯的颜色亮。 财管家 园 fs119.net

      创建绘图要使用的笔刷时需要使用这些颜色。如果正在绘制的灯是亮起的,即使用该颜色。如果绘制的灯是熄灭的,则要使用不同的方法实例化笔刷。下面是熄灭的灯所使用笔刷的代码行: 财 管家园 fs119.net

      bshBrush=NewSolidBrush(Color.FromArgb(60,nCircleColor))

    财软联 盟 fs119.net

      这并不是.NET中较好的方法名,但FromArgB方法的作用是创建笔刷,并通过将笔刷与背景颜色相结合来淡化颜色。第一个参数使用的数字介于0至255之间,数字越小,背景颜色渗透越深。我们使用的值为60,它将大大降低处于熄灭状态的灯的颜色。您可以尝试对该参数使用不同的值(或将它设置成可设置属性),以获得不同的效果。 财软,联盟,fs119.net

      最后,Graphics对象的DrawEllipse方法绘制出该圆,函数结束。记住,该函数需要调用三次以绘制三个不同的圆。

    财 软联盟 fs119.net

    财管.家园.fs119.net

    财,软联盟,fs119.net


    财软联盟 fs119.net

    财管家园 fs119.net

    财软,联盟,fs119.net

      第5步:使控件响应用户 财 软联盟 fs119.net

    财,软联盟,fs119.net

      要允许用户更改灯的颜色,必须检测到用户的鼠标单击操作。有经验的VisualBasic开发人员都知道,可以使用多种方法实现这一目的。我们使用最简单的一种方法,即检测MouseUp事件。下面是检测用户单击并更改Status属性以与之匹配的代码: 财管家 园 fs119.net

    PrivateSubTrafficLight_MouseUp(ByValsenderAsObject,_
    ByValeAsSystem.Windows.Forms.MouseEventArgs)_
    HandlesMyBase.MouseUp
    DimnMidPointXAsInteger=CInt(Me.Size.Width*0.5)
    DimnCircleRadiusAsInteger=nMidPointX
    IfDistance(e.X,e.Y,nMidPointX,CInt(Me.Size.Height/6))_
    <nCircleRadiusThen
    Me.Status=TrafficLightStatus.statusRed
    ExitSub
    EndIf
    IfDistance(e.X,e.Y,nMidPointX,CInt(Me.Size.Height/2))_
    <nCircleRadiusThen
    Me.Status=TrafficLightStatus.statusYellow
    ExitSub
    EndIf
    IfDistance(e.X,e.Y,nMidPointX,CInt((5*Me.Size.Height)/6))_
    <nCircleRadiusThen
    Me.Status=TrafficLightStatus.statusGreen
    EndIf 财,软联盟,fs119.net

    EndSub 财.软联盟.fs119.net

    PrivateFunctionDistance(ByValX1AsInteger,_
    ByValY1AsInteger,_
    ByValX2AsInteger,_
    ByValy2AsInteger)AsInteger
    ReturnCInt(System.Math.Sqrt((X1-X2)^2(Y1-y2)^2))
    EndFunction

    财软联盟 fs119.net

    财管家园 fs119.net

      事件处理非常简单。检查鼠标单击的位置和每个圆心之间的距离。(请注意,圆心分别位于控件下方1/6、1/2和5/6的位置。如果不太明白,可以在纸上画出来看看。)如果计算出的距离小于圆的半径,则更改Status属性。

    财软联盟,fs119.net

      距离由Distance函数使用您可能在代数课中学过的公式计算。请注意,平方根函数是从System.Math命名空间中获得的,数学函数通常都保存在该命名空间中。 财软,联盟,fs119.net

      第6步:清理 财软联.盟.fs119.net

      为了使控件顺利地运作,我们还需要执行一些其他操作。例如,大小改变时需要重新绘制控件。而且,为了不改变控件的比例,我们需要检测影响大小的属性发生更改的时间,然后强制宽度等于高度的三分之一。下面是完成这两项任务的事件处理程序:

    财管家 园 fs119.net

    PrivateSubTrafficLight_Resize(ByValsenderAsObject,_
    ByValeAsSystem.EventArgs)HandlesMyBase.Resize
    Me.Invalidate()
    EndSub

    财软联,盟,fs119.net

    PrivateSubTrafficLight_Layout(ByValsenderAsObject,_
    ByValeAsSystem.Windows.Forms.LayoutEventArgs)_
    HandlesMyBase.Layout
    SelectCasee.AffectedProperty
    Case"Bounds"
    Me.Width=CInt(Me.Height*0.3333)
    CaseElse
    '不执行任何操作
    EndSelect
    EndSub 财管家园 fs119.net

    财管.家园.fs119.net

      最后,设置控件在工具箱中使用的图标。控件已经有一个看似齿轮的默认图标,但是我们要使用VisualStudio.NET附带的红绿灯图标。 财管.家园.fs119.net

    财.管家园.fs119.net

    财管家园 fs119.net

    财管家,园,fs119.net


    财软,联盟,fs119.net

    财软联盟 fs119.net

      控件的工具箱图标是由名为ToolboxBitmap的类中的特性设置的。在以PublicClass开始的行上面插入以下行: 财管家,园,fs119.net

    <ToolboxBitmap("C:\ProgramFiles\MicrosoftVisualStudio
    .NET\Common7\Graphics\icons\Traffic\TRFFC09.ICO")>_

    财,软联盟,fs119.net

    注意:所有内容都应在一行中。为了便于阅读,我们在Studio后放置了一个回车。粘贴该代码时,要确保它们位于一行中,Studio和.NET之间只需一个空格,并删除回车。如果您已经将VisualStudio.NET安装到其默认位置,那么上述代码将用VisualStudio目录中的图标设置该特性。如果您没有将VisualStudio.NET安装到其默认位置,则需要相应地更改图标的路径名。

      第7步:生成和测试控件 财管家 园 fs119.net

      现在TrafficLight控件的设计就完成了。选择Build|BuildMyControls(生成|生成MyControls),以创建最终的控件库。 财软联盟 fs119.net

      要测试控件,我们需要一个Windows窗体项目。您可以在其他解决方案中执行此操作,但在开发控件所用的解决方案中执行会更容易。从菜单中选择File|AddProject|NewProject(文件|添加项目|新项目)。选择WindowsApplication(Windows应用程序)项目类型,将项目命名为TestTrafficLight。单击OK(确定),启动测试所需的Windows应用程序。

    财管,家园,fs119.net

      必须先将TrafficLight控件放到工具箱中,才能将其拖放到测试应用程序的空白窗体1中。右键单击工具箱中的Windows窗体选项卡,然后选择CustomizeToolbox(自定义工具箱)。选择.NETFrameworkComponents(.NETFramework组件)选项卡,然后单击Browse(浏览)按钮。浏览到您的MyControls项目所在的位置,然后转到该项目的/bin目录。选择MyControls.dll组件并单击OK(确定)。现在,该对话框应如图2所示。

    财软联.盟.fs119.net

    财管.家园.fs119.net

      图2:在CustomizeToolbox(自定义工具箱)对话框中,TrafficLight控件被选中。 财.管家园.fs119.net

      您可以看到TrafficLight控件旁边有一个复选标记。单击OK(确定)按钮,在工具箱的WindowsForms(Windows窗体)选项卡上,TrafficLight控件将出现在控件列表的底部。图3显示了底部为TrafficLight控件的工具箱。

    财管家园,fs119.net

    财软 联盟 fs119.net

    图3:工具箱底部的TrafficLight控件
    财管 家园 fs119.net

      现在,您可以将TrafficLight控件拖放到TestTrafficLight的空白窗体1中。默认情况下,它被命名为TrafficLight1。您可以调整控件的大小,重新设置控件的属性,包括Status属性,该属性有一个下拉菜单,菜单中包含该属性的三个可能的值。请注意,调整控件的大小或更改其属性时,控件将在设计器中自动刷新。

    财软联 盟 fs119.net

    财管家园.fs119.net

    财软联盟,fs119.net


    财软联盟.fs119.net

    财软.联盟.fs119.net

    财,软联盟,fs119.net

      要恢复属性的默认值,请将Status属性更改为statusRed。然后,右键单击Properties(属性)窗口中的Status(状态)属性,并选择Reset(重置),如图4所示。该属性将更改回statusGreen。如果将BorderWidth属性设置为1之外的其他值,也可以使用同样的方法恢复其默认值。

    财管家园.fs119.net

    财软联.盟.fs119.net

      图4:Properties(属性)窗口中Status(状态)属性的Reset(重置)选项。请注意窗口底部有关Status(状态)属性的说明。 财软联盟 fs119.net

      如果需要,还可以为控件插入StatusChanged事件。然后,可以使用该事件中的以下代码行查看更改后的状态:

    财软联 盟 fs119.net

      MsgBox("新状态为"&NewStatus.ToString)

      要在操作中测试该控件,您需要启动TestTrafficLight项目。此时,它还不是该解决方案的启动项目,因此您需要解决它。在SolutionExplorer(解决方案资源管理器)中,右键单击Solution(解决方案)名称-SolutionExplorer(解决方案资源管理器)中的第一行。选择Properties(属性),然后将SingleStartupProject(单启动项目)设置从MyControls更改为TestTrafficLight,然后单击OK(确定)。 财管.家园.fs119.net

      按F5键启动该项目。将显示带有TrafficLight控件的窗体。测试控件:按下不同的灯,查看它们是否亮起。您还可以测试BorderWidth属性,尝试在代码中设置灯的Status属性。

    财管家园 fs119.net

      小结

    财管家园.fs119.net

      尽管TrafficLight是一个简单的控件(虽然曾有开发人员要把它用到真实的项目中),但它却显示了开发复杂控件所需要的所有原理,包括:

  • 在控件中添加属性。
  • 使用默认值和说明,使属性与VisualStudioIDE协调。
  • Paint事件中插入逻辑以绘制控件。
  • 在绘图逻辑中使用GDI。
  • 为控件设置位图,以便在工具箱中显示。
  •   创建复杂控件的关键在于熟悉GDI的绘图能力。如果理解了TrafficLight绘制边框和彩色圆的原理,那么您就有了一个好的起点。关键是,有了VisualBasic.NET,即使象我这么懒惰的程序员也能创建高级的Windows窗体。

    财管.家园.fs119.net

    财.管家园.fs119.net

    财软联 盟 fs119.net


    上一篇:如何用VB.Net创建一个三层的数据库应用程序
    下一篇:运用VB.net创建Web服务访问程序

    精品课程推荐