正在阅读:如何在VB.NET中创建Windows应用程序如何在VB.NET中创建Windows应用程序

2005-08-31 10:03 出处: 作者:苦丁 责任编辑:moningfeng

  对于一个Visual Basic程序员来说,创建的每一个应用程序都是胖客户端的。Web开发从来不是VB的目的,VB专注于开发具有Windows用户界面的单机或C/S结构应用程序,使得VB语言和其窗体引擎得到紧密的结合。在VB6中没有必要区分语言和创建界面的工具,但是在.NET中却是非常有必要的。

  在VB.NET中,创建"标准"windows 应用程序的技术是.NET框架的一部分,在任何其它.NET语言中也都可以实现,这是和原先有着巨大改变的。在以下几个部分中,在详细讨论VB.NET中新的窗体技术如何工作。

  崭新的Windows 窗体模型

  在.NET中的窗体改变了在VB6中的窗体模型,窗体不再是一个专门的文件。编辑窗体或窗体上的控件的属性会产生与你在代码里设置属性一样的真正的VB.NET代码,下面我们通过一个例子来剖析一下VB.NET的新窗体设计器的特点,并看一下通过可视化的编辑所产生的代码。

  让我们来看一下窗体Form1的代码,你可以看到这个窗体中的按钮的点击处理程序和一个被称作Windows Form Designer generated code的区域,如下图所示:


  在这个区域里,你会看到几个关键的元素:

  一个窗体的构造器(constructor)(a Sub New())

  一个释放(Dispose)程序

  窗体中所有控件的声明

  一个名为InitializeComponent的子程序

  构造器和释放程序与VB6中的Class_Initialize和Class_Terminate事件基本等效。设计器所产生的代码的实质是其他两部分-控件声明的列表和InitializeComponent程序。看一下创建这个简单的例子所产生的代码。如下:

'NOTE: The following procedure
is required by the Windows Form Designer
'It can be modified using
the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Button1
As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Button1

'
Me.Button1.Location =
New System.Drawing.Point(96, 88)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'Form1
'
Me.AutoScaleBaseSize =
New System.Drawing.Size(5, 13)
Me.ClientSize =
New System.Drawing.Size(292, 273)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub


  从上面的代码中的12到15行,你可以看到是用来设置按钮的大小等属性。

  假若你增加一些你自己的代码,即使是一些简单的代码,将会产生意想不到的结果。

  在这儿,我们只增加一行简单的代码如下:

'
'Button1
'
Me.Button1.Location =
New System.Drawing.Point(96, 88)
Me.Button1.Name = "Button1"
Debug.WriteLine("Testing!")
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"


  产生的结果如下图


  因此除了构造器内的代码,你最好不要直接修改它,而是尽量通过可视化界面来改变其属性。

  .NET中的事件处理机制

  在vb6中,事件处理程序关联到相应的对象上完全依赖于处理程序的名字。在.NET中怎么关联一个特定的事件处理程序到一个对象的事件呢?

  1、使用WithEvents和Hadles关键字

  这是Windows窗体设计器默认使用的模型。控件的对象在声明的时候用WithEvents关键字来表示,事件处理程序在程序声明后提供一个Handles 对象名.事件 子句。

  通过这两个部分Handels和WithEvents,把对象的事件和事件处理程序关联起来。让我们回到第一个例子上来,看一下设计器是如何把按钮的点击事件和相应的代码处理程序联合起来的。让我们看一下按钮本身定义中的第一行代码:

Friend WithEvents Button1
As System.Windows.Forms.Button


  按钮在声明的时候使用了WithEvent关键字。双击Button1,窗体设计器会为默认的点击事件自动产生一个新的事件处理程序。设计器产生的程序在末尾添加了Handles Button1.Click的声明(如下所示)

Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
MsgBox("Hello World!")
End Sub


  至此,虽然语法可能有点区别,但是总体思路是和VB6中的事件处理机制是基本相同的。不过使用WithEvents和Handles可以实现一些新的特点。例如你可以指定一个特定的事件处理程序处理多个事件。你可以在窗体中创建第二个按钮,然后双击它,产生的第二个事件处理程序如下:

Private Sub Button2_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button2.Click
End Sub


  同样你也可以修改Button1的事件处理程序中的Handles属性如下:

Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click, Button2.Click

MsgBox("Hello World!")
End Sub


  现在,无论点击哪个按钮,会执行同样的处理程序。同样通过在多个处理程序的Handles子句中指定同一个事件,一个事件也可以对应多个处理程序:

Private Sub ClickEvent1( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button2.Click

MsgBox("ClickEvent1")
End Sub
Private Sub ClickEvent2( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button2.Click
MsgBox("ClickEvent2")
End Sub


  当Button2被点击的时候,在ClickEvent1和ClickEvent2中的代码都会被执行。

  2、通过使用AddHandler/RemoveHandler手动处理事件

  这种方法可以允许在运行时动态地将事件与一个或更多的事件处理程序连接或者断开。例如在一个空的窗体上有一个按钮和一个CheckBox.当CheckBox被压下后,通过使用AddHandler,按钮的点击事件被关联到一个简单的事件处理程序,显示一个消息框。当CheckBox在不被选中的时候,使用RemoveHandler来将事件处理程序与按钮分离开来。


Private Sub CheckBox1_CheckedChanged( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles CheckBox1.CheckedChanged
If CheckBox1.Checked Then
AddHandler Button1.Click, _
AddressOf myClickHandler
Else
RemoveHandler Button1.Click, _
AddressOf myClickHandler
End If
End Sub
Private Sub myClickHandler( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs)
MsgBox("Event Handled!")
End Sub



  缺少控件数组

  对于VB6开发者来说,在VB.NET中感觉很不方便的一点是缺少了控件数组。有什么办法来实现与控件数组相同的效果呢?从上文的.net中的事件处理机制我们知道,在.net中允许多个对象的事件使用同一个事件处理程序,那么结合一个标准数组就不难实现控件数组的效果了。

  下面是一个简单的例子。

  1.创建一个新的VB.NET Windows 应用程序。

  2.在窗体上放置五个radio button,并在窗体上增加一个label。

  3.双击一个radio button,会转到它的CheckedChanged事件处理程序,修改 Handles子句以包含其他四个的CheckedChanged事件。

Private Sub RadioButton1_CheckedChanged( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles RadioButton1.CheckedChanged, _
RadioButton2.CheckedChanged, _
RadioButton3.CheckedChanged, _
RadioButton4.CheckedChanged, _
RadioButton5.CheckedChanged
End Sub


  4.创建一个radio buttons的数组作为一个私有成员变量:Dim radioButtons(4) As RadioButton

  5.创建一个整形私有变量:Dim selectedOption As Integer = 0

  6.在窗体构造器代码中增加代码以把这些radio button填充到数组中

Public Sub New()
MyBase.New()
'This call is required by the
Windows Form Designer.
InitializeComponent()
'Add any initialization after
the InitializeComponent() call
radioButtons(0) = RadioButton1
radioButtons(1) = RadioButton2
radioButtons(2) = RadioButton3
radioButtons(3) = RadioButton4
radioButtons(4) = RadioButton5
End Sub


  7.在刚才的CheckedChanged程序中加入如下代码:

Private Sub RadioButton1_CheckedChanged( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles RadioButton1.CheckedChanged, _
RadioButton2.CheckedChanged, _
RadioButton3.CheckedChanged, _
RadioButton4.CheckedChanged, _
RadioButton5.CheckedChanged
Dim i As Integer = 0
Dim found As Boolean = False
While i < radioButtons.GetLength(0)
And Not found
If radioButtons(i).Checked Then
found = True
selectedOption = i + 1
Label1.Text = CStr(selectedOption)
End If
i += 1
End While
End Sub


  编译运行这个程序,你会发现每次选择不同的radio button的时候,在label中显示相应的序号。是不是和控件数组一样的效果?

  设置你的窗体的大小改变

  在VB6中我每次改变窗体的大小,都不得不在窗体的Resize 事件中编写代码。在vb.net中有许多特点可以让你不写一行代码就可以改变控件的大小。下面我们将了解三种新特点和面板的使用,通过结合使用他们可以增强你的控件管理的灵活程度。

  Docking属性

  这个属性可以被设置为Top,Bottom,Left,Right或Fill。可以使控件紧挨指定的视窗边缘,或者紧挨已放置到相应视窗边缘的其他控件。设置Dock属性为Fill可以使控件调整为充满视窗的整个客户区。


  Anchor属性

  Anchor属性可以被设定为Top,Bottom,Left和Right的任何组合。这可以保持控件的top-left角与视窗边框具有相同的相对位置。设置Anchor属性为Top and Bottom可以垂直地调整控件,保证从视窗底部到控件底部距离相同。


  AutoScrolling 窗体

  AutoScroll特性,允许用户改变窗体的大小,而不改变控件的大小,改变窗体大小的时候会出现滑动条。


  没有默认的窗体实例的编程

  类和对象虽然在VB6中也存在,但是远远没有像在.NET中一样对象无处不在。对于VB6开发者来说,最常碰见的一个问题就是在.NET中缺乏默认的窗体实例。

  VB 6 允许代码直接访问尚未实例化的窗体类;然而VB .NET 却规定在访问任何类之前都要进行实例化,而且必须借助实例来访问类。VB 6能自动生成每个窗体的默认实例,从而允许直接通过窗体名称来访问窗体,可以直接用代码 "Form2.Show" 显示 Form2 的默认实例;然而在 VB .NET 中,这么做只会引发错误,因为 Visual Basic .NET 既不会创建默认的窗体实例,也不允许直接访问尚未实例化的窗体类。

  你只有先创建窗体实例,然后才可以显示窗体外观、访问窗体属性及其控件。在 VB 6 等早期版本中,多个窗体之间的交互通常需要借助默认窗体实例来完成。在 .NET 下实现多窗体交互,进行 .NET 窗体编程时应该牢牢把握下列原则:在访问窗体之前,你必须进行窗体实例化;如果在项目中有多处代码访问同一窗体,则你必须把它的同一实例指针传递给这些代码。

  总结

  以上总体描述了在VB.NET中新的Windows客户端开发的模型,以下几点比较重要:

  Windows窗体是一个新的窗体模型,与VB6的窗体模型相比,有更多新特点。

  在.net中查看所有你创建和设置你的用户界面的代码,有时可以编辑。

  在.NET中事件处理机制不在基于事件处理程序的名字,而是利用Handles关键字。

  由于新增的docking(停靠)和anchoring(锚定)属性,窗体布局比在VB6中更强大了。

  在VB .NET中没有默认的窗体实例。

相关文章

关注我们

最新资讯离线随时看 聊天吐槽赢奖品