Henry手记-VB.net WinForm中的FORM初探(一)

** Henry ** ** 手记- ** ** VB.net WinForm ** ** 中的 ** ** FORM ** ** 初探(一) **

韩睿( 2002.9.25 )

经常有网友在我主持的版面上发贴子或写信直接来问我,为什么 vb.net 和 vb6 差了这么多。当然,问得最多的就是关于窗体的调用,这也是一个与 vb6相比,vb.net具有的 变化最大的特征 — 面向对象(限于篇幅,有关面向对象的基本内容请参看面向对象的书籍)。当有朋友大喊 vb.net 怎么这么这么……(此处删去两字)时,我只得劝他再忍一下,再深入一点,痛过之后的快意会让他理解更美的世界。

一起开始我们今天的历程吧。对于从 vb 学起,没有经过 C++ 与 Java 考验的朋友来说,可能会稍微麻烦一点,有问题请跟我联系吧。


** 一、为什么我的 Form Show 不出来了? **

是不是微软忙晕了?忘了有人有用两个 form 的需求?当然不可能, if 是忘了,那微软就真是疲软了。

曾记否,在 vb 中想在 Form1 中调出 Form2 时是如何的酣畅淋漓:

Form2.show ( 不讨论模式问题 )

但是,在 vb.net 中再写 form2 打一点后,出来的属性框中居然没有我们料想中的 show 了!

原因: _ Visual Basic .NET _ _ 取消了早期版本中的 _ _ “ _ _ 默认窗体实例 _ _ ” _ _ ,并且规定,只有通过引用窗体实例,才能访问窗体的属性、方法及其控件。 _

原来是这样,在 vb.net 中窗体也变成了一个类!我们来剖析一下一个窗体的生成代码吧。请用 vb.net 建立一个 Form : Form3 。然后看一下代码并一句一句分析一下:紫色的注释是我加的,绿色的是系统自带的。

Public Class Form3 ‘ 类的定义方法

Inherits System.Windows.Forms.Form ‘ 告诉我们此类是继承自何处

Region " Windows 窗体生成的代码 ” ‘ # Region 指令用于 折叠并隐藏 Visual Basic .NET 文件中的代码节。通过这一方法可以更好地规划与书写我们的代码了。

Public Sub New () ‘ 类的构造

MyBase .New() ‘ 用于从派生类构造函数中显式调用基类构造函数。这个等会还会说明。

' 该调用是 Windows 窗体设计器所必需的。

InitializeComponent() ‘ 如果你的初始化代码有很多行,你可以建立一个子过程来管理这些代码,子过程的名字就是 InitializeComponent() 。见后面。

' 在 InitializeComponent() 调用之后添加任何初始化

End Sub

' 窗体重写处置以清理组件列表。

‘Overloads 关键字用与现有成员相同的名称来声明属性或方法,但参数列表与原始成员不同。 Overrides 关键字指定属性或方法将重写从基类继承的成员。这个问题不是很清楚,请查一下面向对象的书中重载与继承的相关内容。笔者计划几天后有空会写一篇《 vb.net 的继承与接口》,界时会更详细地进行描述。

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 窗体所必需的

Private components As System.ComponentModel.IContainer

‘System.ComponentModel 命名空间提供用于实现组件和控件运行时和设计时行为的类。 Icontainer 接口 提供容器的功能。容器是在逻辑上包含零个或更多个组件的对象。也就是说通过这样的定义, components 就成为了可包容当前窗口所有组件的容器了。

' 注意:以下过程是 Windows 窗体设计器所必需的

' 可以使用 Windows 窗体设计器修改此过程。

' 不要使用代码编辑器修改它。

 1<system.diagnostics.debuggerstepthrough()> Private  Sub  InitializeComponent() 
 2
 3‘  在  vb.net  中用  &lt; &gt; 表示特性。能完成一些系统提供的独特功能。 
 4
 5'Form3  以下定义的是初始化窗口的属性内容 
 6
 7Me  .AutoScaleBaseSize =  New  System.Drawing.Size(6, 14) 
 8
 9‘  ** AutoScaleBaseSize  ** 属性的值在窗体显示时使用,用来计算该窗体的缩放因子。窗体将自动缩放基大小用作与系统的字体大小进行比较的基准,以确定使用自动缩放时窗体的缩放量。 
10
11Me  .ClientSize =  New  System.Drawing.Size(336, 309) 
12
13Me  .Name = "Form3" 
14
15Me  .Text = "Form3" 
16
17‘用户在窗体上布局控件时,控件的初始化属性也是写在这里的 
18
19End  Sub 
20
21#  End  Region 
22
23End  Class 
24
25这里补充说明一下  ** MyBase  ** 关键字的作用与意义: 
26
27_ MyBase  _ _ 关键字的行为类似于引用类的当前实例的基类的对象变量。  MyBase  _ _ 常用于访问在派生类中被重写或隐藏的基类成员。  _
28
29在上述代码中,  MyBase  指的当然就是  System.Windows.Forms.  Form  类了。 
30
31从而我们可以知道,在  sub new  中声明的  mybase.new  意图在于在  form3  构造时继承下  System.Windows.Forms.  Form  类的初始化内容。同样的  MyBase.dispose  的作用在于利用基类  System.Windows.Forms.Form的析构方法来进行析构。 
32
33总结一下,现在的窗体是一个确确实实的类了,我们应该换个眼光来看待  vb.net  中的  form  了。忘掉那个  vb  中的  form  用法吧,它只不过是  System.Windows.Forms.F  orm  类的一个实例呀。 
34
35那么,回到开头的问题,怎么样来在  vb.net  中实现在  Form1  中调用  Form2  的功能呢?只要把类引用到实例就可以了: 
36
37Dim  frm2  As  New  Form2()  ‘  定义  Form2  类的一个实例 
38
39frm2.Show()  ‘  通过实例去调用类的方法,同样不讨论模式问题 
40
41是不是很简单,那么我再简单引申一下,当我们声明  frm2  时用到了  New  ,自然是利用  form2  类中的  sub new  来构造这个  frm2  。那么我们在哪里来调用  dispose  来析构  new  出来的  frm2  呢? 
42
43Form.Dispose  方法是重写自  Control.Dispose  方法的,那么  Control.Dispose  方法的含义又是怎么样的?它的作用就是:释放由  Control  占用的非托管资源,还可以另外再释放托管资源。当它参数中的  [Visual Basic] 
44
45_ disposing  _ 为  ** true  ** 则释放托管资源和非托管资源;为  ** false  ** 则仅释放非托管资源。  Form  类的  disposing  为  ** true  ** 。 
46
47在关闭窗体时自动调用  dispose  的功能是得益于  .net  的公共语言运行库,运行库自动处理对象布局和管理对对象的引用,当不再使用对象时释放它们。其生存期以这种方式来管理的对象称为托管数据。自动内存管理消除了内存泄漏以及其他一些常见的编程错误。当然它也不是万能的,这不是本文讨论的重点,先按下不表。 
48
49任何类型的  ** Dispose  ** 方法都应该释放它拥有的所有资源。它还应该通过调用其父类型的  ** Dispose  ** 方法释放其基类型拥有的所有资源。该父类型的  ** Dispose  ** 方法应该释放它拥有的所有资源并同样也调用其父类型的  ** Dispose  ** 方法,从而在整个基类型层次结构中传播该模式。要确保始终正确地清理资源,  ** Dispose  ** 方法应该可以被多次安全调用而不引发任何异常。 
50
51当我们关闭一个窗口的时候,会发出一个终止响应,并将该窗口对象(就象上面定义的  frm2  )送入终止队列,公共语言运行库的垃圾回收器跟踪着这个对象的生存期,此时就会调用此对象基类(比如  Form2  )的  Dispose  方法,用于销毁对象并收回资源。 
52
53如果通过  Dispose  还释放不干净或没有调用  Dispose  ,系统的垃圾回收器会调用对象的  ** Finalize  ** 方法进行清除。由于执行  ** Finalize  ** 方法会大大减损性能,所以我们不会一开始就用它去进行清除工作。 
54
55通过这一小节,希望您已经建立起一个概念,  vb.net  中连窗口都成了一个实实在在的类,而且提供了一整套完整的类的解决方案,一改  vb6  中不能实现类继承的缺陷。下一节中,我们将开始进行多窗体编程的讨论。 
56
57\---- 
58
59声明:本文版权与解释权归韩睿所有,如需转载,请保留完整的内容及此声明。 
60
61QQ: 18349592</system.diagnostics.debuggerstepthrough()>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus