henry vb 学习

** Henry ** ** 的 ** ** VB.NET ** ** 之旅(一) ** ** — ** ** 失踪的窗体 ** ** **

韩睿

很久没有新作,架不住朋友们的询问与追问,只得拿些旧作来补上近日没空写作的不足。 惭愧 ing! 这一系列与 ** Henry ** ** 手记 ** 系列不同,是一个角色形式的情景故事,最初发表于《计算机世界》,适用于 VB.net 初学者,老鸟们就不用在我这一系列的文章上浪费时间了。我希望自己有时间以后,能不断继续这一系列的文章,加入大量的工程解决方案。同时,我的 Henry 手记也会继续写下去,以回报长期以来支持我的所有朋友。

** 背景: ** 我叫 Henry ,刚从大学计算机专业毕业,新加入索易公司的 .NET 开发小组 ; 负责带我的头目是大李, .NET 高手,是个幽默又有耐心的家伙 ; 老白是我们部门的头头,经常带给我们古怪又难缠的需求。

第一天上班,白经理就带着我去 .NET 技术小组报到。“大李,这是新来的同事,你要多帮帮他。”老白指着我对一个眼镜后面透着闪闪目光的年轻人说。

“没问题,他会做得很好的。”大李难道会看相不成?还是人家客气呀?不管了,我只要自己努力就对了。

20分钟后,我已经在分配给我的一台P4电脑,WindowsXP平台下打开了Visual Studio.NET的集成编译环境(IDE)开始欣赏了。 一个多漂亮的编译环境呀,可以自选使用时的风格是 VB6 的还是 VC6 的。我选择的是 RAD 性能好的 VB6 风格。

“你刚开始接触 .NET ,在系统培训之前先加深点印象,看看 VB.NET 与 VB6 有什么不同吧。你创建两个窗体,每个窗体上各有一个按钮,点击时隐藏其所在的那个窗体,切换出另一个窗体来。”大李的声音在耳边响起,打断了我对 IDE 的欣赏。但他提的要求也太简单了吧,在 VB6 中只需要两句写在按钮的单击响应中的语句就行了:

两个窗体: Form1与Form2。Form1上的按钮为: Command1,Form2上的按钮为: Command2


Private Sub Command1_Click()

Me.Hide

Form2.Show

End Sub

|

Private Sub Command2_Click()

Me.Hide

Form1.Show

End Sub

于是,我毫不犹豫地在 VS.NET中内开始我的第一个VB.NET的项目了。首先,新建了一个VB.NET的Windows应用程序项目,自动生成了一个Windows Form:Form1,在其上加入一个按钮控件:Button1;然后,添加了一个Windows Form:Form2,在其上加入了一个按钮控件:Button2。

在设计窗口双击 Button1 后,编译器会切换到代码窗口的 Button1 的单击响应代码中。

在代码段中故计重施,当我想写 Form2.Show 时,在 Form2 之后打个点,出现的智能感知菜单中,却没有 Show 这一方法。真奇怪,这怎么可能?难道 VB.NET 改动有这么大。我抬头看了看站在我身旁的大李。

大李立刻面露微笑,看来是正中他的圈套。他手指向屏幕,点了点 Form1 中的代码的开头处:

Public Class Form1

Inherits System.Windows.Forms.Form


不笨的我立刻就明白了,现在的 Form1是一个从System.Windows.Forms.Form继承下来的类了,调用的时候当然需要先实例化了,哈,也不难嘛。马上动手:

Private Sub Button1_Click( ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button1.Click

Me .Hide()

Dim frm2 As New Form2() ‘ 实例化 Form2类,得到一个对象

frm2.Show()

End Sub


在 Form2的Button2的单击事件中也相似地写了一段代码,运行一下,和VB6的效果差不多了。正在得意中,大李走过来,在我的Form1中添加了一个文本框textbox1,清空其中的文字。然后运行了一下程序。在运行中,他在文本框里写了几个字:“Henry的作品”,然后点击Button1切换到Form2,接着点击Button2,重新出现的Form1的文本框中却变成了空白。

“这……”我一时语塞,慢慢地想起点什么,“应该是程序通过 New 构造方法,每次点击按钮都会重新实例化一次 Form 类吧?所以每次重新出现的窗体都不是以前曾经出现过的那个。那以前的窗体也就失踪了,调不出来了。 ”

“ 失踪? ” 大李不禁笑了起来, “ 对呀,失踪在内存中。你每实例化一次,系统就会开辟一块内存给一个对象,并会有相应的线程对其进行控制与管理。如果作为进程中主线程的第一个 Form1 被 Hide 起来,没有关闭它,那么即使你关闭后来新创建的所有窗体,进程也不会被中止。那么,用什么方法去找回你失踪的窗体,或者说怎么样就只使用一个对象,不再每次实例化呢? ”

“全局对象!”我脱口而出,感觉到大李不置可否,只好硬着头皮继续说:“利用全局变量,使 Form1 与 Form2 只实例化一次,这样就可以了。 ”

然后,在大李的注视下,我开始实施我的计划:

再创建一个模块文件 :module1.vb ,并且同时在:

解决方案管理器 - 〉项目名 .sln - 〉右点鼠标 - 〉属性 - 〉通用属性 -> 常规 -> 启动对象 - 〉改为 Module1 。让程序启动后先运行 Module1 中的代码指令,然后编写代码如下:

'Module1.vb

Module Module1

Public frm1 As New Form1() ‘定义Form1的公用变量实例

Public frm2 As New Form2() ‘定义Form1的公用变量实例

Sub Main()

Application.Run(frm1) ‘这句话表明程序启动了modele后,会接下来运行frm1,即form1的一个实例。主线程就成为运行期的frm1了。

End Sub

End Module


这样一来, frm1、frm2就成为全局变量了,在Button1与Button2的单击响应代码中只要写:frm1.show就可以了。

再运行程序,可以了,“ Henry的作品”一直都会保持在Form1中的文本框里。

大李老哥没等我欢笑起来就再次出手,在 frm1 隐藏起来的时候,关闭了 Form2 窗口( frm2 实例),桌面上什么窗体都没有了,进程又一次被陷入在无法中止的情况下。 My God ,面向对象的 VB.NET ,爱你难道真的这么难 ……

** Henry ** ** 的 ** ** VB.NET ** ** 之旅 ** ** ( ** ** 二 ** ** )— ** ** 构造与析构 ** ** **

韩睿

大李在 Form1 窗体的实例被隐藏的时候,关闭了 Form2 窗体的实例,使我失去了对主线程的人工控制,进程无法正常关闭了。只好使用 Ctrl+Alt+Del 调出系统进程管理器,强行中止了该进程。为了避免抬头看见大李的笑脸,我只好低头想办法。

有了,我只要能截获 Form2实例关闭的消息,不就可以再调出隐藏的主线程窗体了吗?在Form2的基类事件(Base Class Event)中重载Closing方法进行处理:

Private Sub Form2_Closing( ByVal sender As Object , ByVal e As _

System.ComponentModel.CancelEventArgs) Handles MyBase .Closing

frm1.Show()

End Sub


哈,很方便,我关闭了 Form2 窗体的实例后,被隐藏的那个 frm1 又出现了。

“嗯,”大李终于发话了,“你再点击一下 Form1 窗体上的 Button1 试试。 ”

我背心一凉,隐隐感觉大李等待着的就是这个时候。无奈的我还只能照他说的去做。果然,弹出一个出错窗口:

“你关闭了 frm2 这个 Form2 的实例,也就结束了这个对象的生存期, ” 大李看来是蓄势已久了, “ 这就是出错提示中所说的 ‘ 无法访问名为 <SPAN lang=EN-US style="FONT-SIZE: 9p

Published At
Categories with Web编程
Tagged with
comments powered by Disqus