VB.NET多窗体实际编写方式讲解(上)

原创|其它|编辑:郝浩|2010-01-12 10:27:53.000|阅读 1380 次

概述:作为一个优秀的编程人员,能够熟练的运用两种以上的编程语言是必要的基本技能。那么VB.NET这样一款功能强大的开发语言应该是程序员们首选之一。在这里先从一个VB.NET多窗体编程的例子来体验一下它的强大性。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

  作为一个优秀的编程人员,能够熟练的运用两种以上的编程语言是必要的基本技能。那么VB.NET这样一款功能强大的开发语言应该是程序员们首选之一。在这里先从一个VB.NET多窗体编程的例子来体验一下它的强大性。

  前言

  在微软 Visual Basic 6.0 中,一条简单的 “Form2.Show” 语句就能显示项目中的第二窗体 (Form2)。然而,它在 Visaul Basic .NET 中却行不通了,因为 .NET 版在窗体处理机制上有了很大的变化。刚刚转向 .NET 版的 Visaul Basic 程序员实在难以接受这么大的变化,因为现在连“显示第二窗体”这么简单的任务都无从下手。我希望能够通过本文向大家介绍 Visaul Basic .NET 与早期的 Visual Basic 在窗体处理机制上有哪些不同之处,以及如何按照 .NET 的模式进行VB.NET多窗体编程。

  Visual Basic 6.0 对 Visual Basic .NET

  窗体(窗体类)正如其它类一样,无论在哪个版本的 Visual Basic 中都是必不可少的。VB.NET多窗体也有属性、方法和事件,且在同一个项目中也允许创建多个窗体实例。例如:假设你在 Visual Basic 6.0 项目中定义了一个窗体 Form2 ,则你可以创建它的 3 个实例并同时显示出来。代码如下:


Dim myFirstForm As Form2    
Dim mySecondForm As Form2    
Dim myThirdForm As Form2    
Set myFirstForm = New Form2    
Set mySecondForm = New Form2    
Set myThirdForm = New Form2    
myFirstForm.Show    
mySecondForm.Show    
myThirdForm.Show 

 

  以上代码用 3 条 Set 语句生成了 3 个 Form2 实例。你可以把它原封不动地搬到 Visual Basic .NET 中运行,它照样能够正确显示 3 个 Form2 窗体。在这里,“Form2” 其实相当于一个普通的类。Visual Basic 6.0 允许代码直接访问尚未实例化的窗体类;然而Visual Basic .NET 却规定在访问任何类之前都要进行实例化,而且必须借助实例来访问类。这种变化当然有可能造成许多疑惑。Visual Basic 6.0 等早期版本能自动生成每个窗体的默认实例,从而允许直接通过窗体名称来访问窗体。例如:在 Visual Basic 6.0 项目中,可以直接用代码 “Form2.Show” 显示 Form2 的默认实例;然而在 Visual Basic .NET 中,这么做只会引发错误,因为 Visual Basic .NET 既不会创建默认的窗体实例,也不允许直接访问尚未实例化的窗体类。

  这就是 Visual Basic .NET 与早期 Visual Basic 在窗体处理机制上的关键区别——你只有先创建窗体实例,然后才可以显示窗体外观、访问窗体属性及其控件。它们还有另一个区别:Visual Basic 6.0 项目自动创建的默认窗体实例都能被当成全局变量使用,也就是说,项目中的任何代码都能直接引用VB.NET多窗体,并且每次被引用的都是该窗体的同一个实例。例如:你可以在窗体中 button 控件的 Click 事件处理程序里用代码 “Form2.Show” 显示 Form2 窗体,然后用下列代码改变 Form2 中某个 textbox 控件 (TextBox1)的内容:


  Form2.TextBox1.Text = "Fred"

  可是,你在 Visual Basic .NET 中运行它却会得到一条错误消息:“Reference to a Non-Shared Member Requires an Object Reference”(引用非共享类成员必须使用对象指针)。这是在提醒你:你正在访问的类尚未进行实例化。有一个简便的解决方案:当你在调试过程中得到上述错误消息时,就把相应的语句:


 Form2.Show()

  改成:


Dim myForm2 As New Form2() myForm2.Show()

  此方案适用于大多数场合。然而,当项目中还有其它代码访问同一个 Form2 实例 (比如改变其中 TextBox1 的文本) 时,你可能会考虑把下列语句:


 Form2.TextBox1.Text = "Fred"

  改成:


 Dim myForm2 As New Form2() myForm2.TextBox1.Text = "Fred"

  不幸的是,这段代码创建了一个新的 Form2 实例,结果你所访问的VB.NET多窗体不再是原先的 Form2 ,这岂不麻烦了!更坏的是,你不会因此而得到任何错误消息提示,同时你先前调用 Show() 显示的 Form2 窗体也不会发生任何变化。

  升级向导如何解决它

  如果你用升级向导 (Upgrade Wizard) 把 Visual Basic 6.0 项目升级为 Visual Basic .NET 版,则它会在每个窗体中自动添加一段特殊代码,通过显式创建窗体实例来模拟早期 Visual Basic 版本中的默认实例化机制。此段代码被包裹于标号为 “Upgrade Support”的代码区块内,借助一个新增的 Shared 属性来生成当前窗体的实例:


Private Shared m_vb6FormDef
Instance As Form1    
Private Shared m_Initializing
DefInstance As Boolean    
Public Shared Property 
DefInstance() As Form1    
Get    
If m_vb6FormDefInstance Is 
Nothing _    
OrElse m_vb6FormDefInstance.
IsDisposed Then    
m_InitializingDefInstance = True    
m_vb6FormDefInstance = New Form1()    
m_InitializingDefInstance = False    
End If    
DefInstance = m_vb6FormDefInstance    
End Get    
Set(ByVal Value As Form1)    
m_vb6FormDefInstance = Value    
End Set    
End Property 

 

  代码中的 DefInstance 是一个 Shared 属性,它能以 “窗体名.DefInstance” 的形式直接访问。它所在项目中的任何代码访问它都将得到同一个窗体实例。这样,你就能模拟 Visual Basic 6.0 项目对VB.NET多窗体的直接引用了,只不过在代码中以 “Form2.DefInstance” 代替 “Form2” 而已。

  这时,你只需用 Form2.DefInstance.Show() 和Form2.DefInstance.TextBox1.Text = "Fred" 分别替换原先对 Form2 相应的直接引用就大功告成了。假如你不用升级向导,而是在 Visual Basic .NET 窗体中手工插入上述代码 (以及升级向导在窗体的 New过程中自动添加的代码),也行。当然了,你并不一定非要修改窗体代码,因为有一种编程模式可以在 .NET 项目中模拟默认窗体实例的创建。本文将用余下的篇幅来介绍这种编程模式。

  VB.NET多窗体之间的交互

  在 Visual Basic 6.0 等早期版本中,多个窗体之间的交互通常需要借助默认窗体实例来完成。下面我将结合某些具体的编程任务来讲解如何在 .NET 下实现多窗体交互,希望它能对你的开发任务有所帮助。

  保持窗体引用的全局性

  前面提到,进行 .NET 窗体编程时应该牢牢把握下列原则:在访问窗体之前,你必须进行窗体实例化;如果在项目中有多处代码访问同一窗体,则你必须把它的同一实例指针传递给这些代码。对于早已习惯了直接把默认窗体实例当成全局变量来使用的 Visual Basic 6.0 程序员来说,这可是个严重的挑战。好在 .NET 为你提供了两条出路:其一,把窗体实例指针保存在全局变量中;其二,把窗体实例指针传递给任何需要访问它的窗体、类、模块或者过程。

  .NET 中的数值全局化

  我以前曾经指出,Visual Basic .NET 不支持全局变量,现在我又要说,在 .NET 中可以在某种程度上实现数值全局化。这算不算此一时,彼一时?不,我不是那种人。Visual Basic .NET 确实不支持全局变量,然而它借助 Shared (相当于 C# 中的 static) 变量却能模拟全局变量。事实上,前面介绍的 Visual Basic 升级向导自动添加到窗体代码中的 DefInstance 属性就是 Shared 类成员。无论容纳 DefInstance 属性的窗体类是否已经实例化,它都能被项目中的任何代码所引用。象这样的 Shared 属性不就相当于全局变量吗?因此,你可以创建这样的类:


Public Class myForms    
Private Shared m_CustomerForm 
As CustomerForm    
Public Shared Property 
CustomerForm() As CustomerForm    
Get    
Return m_CustomerForm    
End Get    
Set(ByVal Value As CustomerForm)    
m_CustomerForm = Value    
End Set    
End Property    
End Class  


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:网络转载

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP