测试环境:windows 7和Microsoft Visual Studio 2015 很多文章里都说在Visaul Basic .NET中显示窗体之前必须先实例化,经测试,也可以与旧Visual Basic 6.0 一样不经实例化直接Form1.Show显示窗体。 一、正确显示窗体新建一个窗体应用程序,再添加一个模块和一个窗体。如图: Module Module1 Public Sub Main() 'IF语句,符合条件则显示窗体Form1,这里略过直接显示窗体 Form1.Show() End Sub End Module 测试项目,发现窗体一闪而过,为什么没有长时间显示窗体呢? Module Module1 Public Sub Main() 'IF语句,符合条件则显示窗体Form1,这里略过直接显示窗体 Form1.ShowDialog() End Sub End Module 测试项目,代码执行到 Form1.ShowDialog()这句就不再继续向下执行,直到关闭窗体Form1后才往下执行余下代码。 Module Module1 Public Sub Main() 'IF语句,符合条件则显示窗体Form1,这里略过直接显示窗体 '声明变量 Dim frm As Form1 '实例化窗体 frm = New Form1 '显示窗体 frm.ShowDialog() End Sub End Module 二、窗体间互相传值分别在两个窗体上添加3个按钮和一个Label控件。如图: Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Form2.Show() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Form2.Label1.Text = "Form2,你好!" End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Form2.Label1.Text = "" End Sub End Class Public Class Form2 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Form1.Label1.Text = "Form1,感谢你!" End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Form1.Label1.Text = "" End Sub End Class 以上代码是按旧Visual Basic 6.0语言编写的,但并没有出现其他文章里所说不实例化就会报错,代码能够执行并很好完成窗体间相互传值的任务。 后续:经多方阅读后了解到,上述是使用窗体的共享方法Show来显示窗体,用于与VB6兼容,但不推荐使用。即: Form1.Show() 共享方法可以不用先实例化窗体就进行了显示,这样显示的是默认的窗体实例。在包含窗体的项目中的任何地方都可以使用这个默认窗体。默认的窗体实例只有一个,因此任何指向它的引用实际上使用的都是同一个底层窗体实例。 三、测试实例化后再显示和传值模块代码修改为: Module Module1 Public Sub Main() 'IF语句,符合条件则显示窗体Form1,这里略过直接显示窗体 '声明变量 Dim frm As Form1 '实例化窗体 frm = New Form1 '显示窗体 frm.ShowDialog() End Sub End Module 窗体代码修改为: Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim frm2 As Form2 frm2 = New Form2 frm2.Show() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim frm2 As Form2 frm2 = New Form2 frm2.Label1.Text = "Form2,你好!" End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Dim frm2 As Form2 frm2 = New Form2 frm2.Label1.Text = "" End Sub End Class 测试一下项目,点击Button1可以正确显示窗体 Form2,可是Button2和Button3却无法向Form1传值,是不是也要加一句frm2.Show()?试试看! Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim frm2 As Form2 frm2 = New Form2 frm2.Label1.Text = "Form2,你好!" frm2.Show() End Sub 测试项目,可以传值了,只是并不是向原来的Form1传值,而程序反而又蹦出了一个Form1,再点一次按钮又蹦出一个Form1,再点再蹦……,如图: 1、保持窗体引用的全局性在访问窗体之前,最好进行窗体实例化,如果在项目中有多处代码访问同一窗体,可以把它的同一实例指针传递给这些代码,即把窗体实例指针保存在全局变量中。 Module Module1 '声明一个全局变量 Public frm1 As Form1 Public Sub Main() 'IF语句,符合条件则显示窗体Form1,这里略过直接显示窗体 frm1 = New Form1 frm1.ShowDialog() End Sub End Module 窗体Form1代码修改为: Public Class Form1 Private frm2 As Form2 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load '加载窗体时实例化 frm2 = New Form2 End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click frm2.Show() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click frm2.Label1.Text = "Form2,你好!" frm2.Show() End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click frm2.Label1.Text = "" frm2.Show() End Sub End Class 窗体Form2代码修改为: Public Class Form2 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click frm1.Label1.Text = "Form1,感谢你!" End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click frm1.Label1.Text = "" End Sub End Class OK,现在可以正确传值了,测试结果如图: 2、重写窗体构造函数什么是重写?就是不要原来的无参数构造函数了,改成自己写的带参数构造函数。 Public Sub New() ' 此调用是设计器所必需的。 InitializeComponent() ' 在 InitializeComponent() 调用之后添加任何初始化。 End Sub 这个是窗体默认的无参数构造函数,现在我们重写一个有参数的构造函数。如下代码: Private Frm1 As Form1 Public Sub New(ByVal frm As Form1) MyBase.New() ' 此调用是设计器所必需的。 InitializeComponent() ' 在 InitializeComponent() 调用之后添加任何初始化。 Me.Frm1 = frm End Sub 这里传入的参数是一个对象,即Form1窗体,当然你也可以把参数改成字符串等其他数据类型。 Frm2 = New Form2(Me) 原来是不带参数的,因为上面已经修改了Form2的构造函数,所以此时实例化Form2时不再调用默认构造函数,而是需要我们指明参数再实例化。 Module Module1 '声明一个全局变量 Public frm1 As Form1 Public Sub Main() 'IF语句,符合条件则显示窗体Form1,这里略过直接显示窗体 frm1 = New Form1 frm1.ShowDialog() End Sub End Module Form1代码: Public Class Form1 Private frm2 As Form2 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load '加载窗体时实例化 Frm2 = New Form2(Me) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click frm2.Show() End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click frm2.Label1.Text = "Form2,你好!" frm2.Show() End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click frm2.Label1.Text = "" frm2.Show() End Sub End Class Form2代码: Public Class Form2 Private Frm1 As Form1 Public Sub New(ByVal frm As Form1) MyBase.New() ' 此调用是设计器所必需的。 InitializeComponent() ' 在 InitializeComponent() 调用之后添加任何初始化。 Me.Frm1 = frm End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Frm1.Label1.Text = "Form1,感谢你!" End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Frm1.Label1.Text = "" End Sub End Class 经测试,正确实现相互传值。 四、迷惑不用实例化就可以很方便的调用窗体和向窗体传值,为什么Visaul Basic .NET要如此多事,非要整个实例化才显得更高大上吗?就因为是面向对象编程?那为什么还可以象旧Visual Basic 6.0 那样不实例化调用窗体呢? 更多阅读:再谈WinForm窗体间相互传值(单值、多值)——属性、委托和事件本文参考了以下博文: |
|