none
VB2008速成版中窗体调用的问题,有什么方法可以把所有窗体(而不是窗体的实例)放入一个集合里? RRS feed

  • 问题

  • 比如一个click 事件引发一个过程
    Dim fm2 As new Form2
    fm2.ShowDialog()
    或者
    Form2.ShowDialog()

    的执行结果是不一样的

    如果一个程序有n多个窗体,想一次性对所有窗体的标题进行修改(不论窗体是否加载)如何可以实现?

    我能想到的就是把Form1,Form2,Form3......(这些窗体的名字可能没有什么规律,不一定就是按照123的顺序)放到一个集合中然后用循环语句修改text属性。如何能够找到这些窗体并创建一个窗体的集合?可以手动一个个的添加但是我自己都不喜欢这样。

    用反射好像能够列出窗体的名称但是因为要用组件的类型创建一个新的实例,这样形成的窗体就是原窗体的一个实例而不是原先的窗体了。

    怎么解决呢?
    2009年6月1日 6:20

答案

  • 比如一个click 事件引发一个过程
    Dim fm2 As new Form2
    fm2.ShowDialog()
    或者
    Form2.ShowDialog()

    的执行结果是不一样的

    如果一个程序有n多个窗体,想一次性对所有窗体的标题进行修改(不论窗体是否加载)如何可以实现?

    我能想到的就是把Form1,Form2,Form3......(这些窗体的名字可能没有什么规律,不一定就是按照123的顺序)放到一个集合中然后用循环语句修改text属性。如何能够找到这些窗体并创建一个窗体的集合?可以手动一个个的添加但是我自己都不喜欢这样。

    用反射好像能够列出窗体的名称但是因为要用组件的类型创建一个新的实例,这样形成的窗体就是原窗体的一个实例而不是原先的窗体了。

    怎么解决呢?
    、 你可以设置将你的主窗体设置为MDI父窗体 即将IsMdiContainer设置为true 然后这个窗体的按钮事件处理中 比如 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim form2 As Form2 = New Form2 form2.MdiParent = Me form2.Show() End Sub 在通过父窗体的MdiChildren 这个属性 就可以获取所有的子窗体的数组Form[]
    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月1日 11:27
    版主
  • 个人觉得Form2.showDiaolog是调用的共享的 他的生命周期应该是会在主窗体关闭之前的
    而第二个通过应该在这个过程执行完后就被回收了因为是个局部变量
    我个人是这样理解的哈......
    不过很久没弄VB.Net的了 很多东西都搞忘了


    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月1日 15:08
    版主
  • 你好!
         我向朋友请教了这个问题,看来我上面的说法有误,实际上这两种写法都是被VB.NET支持的:
         第一种写法:
    Dim myform2 As Form2 = New Form2
    myform2.ShowDialog()
    
    

         这个没有太多解释的,只是自己实例化一个新的实例,然后调用ShowDialog();
        
         第二种写法:
    Form2.ShowDialog()
         这个比较有意思了,实际上仅仅是语法上的支持,在编译器看来,上面的代码相当于这行代码:
    MyProject.Forms.Form2.ShowDialog()
         Forms是一个集合类,Form2是这个类的一个属性,获取这个属性的时候在内部会实例化生成一个Form2的实例

    就如同你理解的,这两种写法使用的是不同的实例!
    他支持第二种语法实际上是为了兼容过去VB6的语法,在VB.NET下强烈推荐使用第一种写法!


    周雪峰
    2009年6月1日 15:15
    版主

全部回复

  • 你好!
         你的意思是不是想把窗体的类型(而不是窗体的实例)放到一个集合里管理,,如果是这样的话,可以保存窗体的Type实例在一个集合里!
    周雪峰
    2009年6月1日 11:00
    版主
  • 比如一个click 事件引发一个过程
    Dim fm2 As new Form2
    fm2.ShowDialog()
    或者
    Form2.ShowDialog()

    的执行结果是不一样的

    如果一个程序有n多个窗体,想一次性对所有窗体的标题进行修改(不论窗体是否加载)如何可以实现?

    我能想到的就是把Form1,Form2,Form3......(这些窗体的名字可能没有什么规律,不一定就是按照123的顺序)放到一个集合中然后用循环语句修改text属性。如何能够找到这些窗体并创建一个窗体的集合?可以手动一个个的添加但是我自己都不喜欢这样。

    用反射好像能够列出窗体的名称但是因为要用组件的类型创建一个新的实例,这样形成的窗体就是原窗体的一个实例而不是原先的窗体了。

    怎么解决呢?
    、 你可以设置将你的主窗体设置为MDI父窗体 即将IsMdiContainer设置为true 然后这个窗体的按钮事件处理中 比如 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim form2 As Form2 = New Form2 form2.MdiParent = Me form2.Show() End Sub 在通过父窗体的MdiChildren 这个属性 就可以获取所有的子窗体的数组Form[]
    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月1日 11:27
    版主
  • 多谢版主。

    说的好像就是我想要的东西。麻烦能多指点一下吗。刚刚开始学习。这个问题折磨块一周了。

    我这么理解看对不对


    Dim fm2 As new Form2
    fm2.ShowDialog()

    frm2是Form2 class (类型) 的一个instance(实例)。

    我想得到的是Form(i)(i=1~n) class 的集合这样就可以对各个Form上的控件和Form的属性进行调整。这样调整也会留在程序中(因为是用ShowDialog方法,这个方法好像并不将窗体上的控件清零)这样打开别的窗体的时候调整的结果也可以显示出来。也就是你说的“窗体的类型”放到一个集合中。

    但是如何获得窗体Type实例?是不是用反射?

     

    集合是指list,array,还是collection?还是都可以?

    多谢了。

    2009年6月1日 11:28
  • 多谢提示,

    老师说,我也就刚知道子窗体和父窗体的概念,看来要学习了。还有,这个数组包括父窗体本身吗?

    谢谢
    2009年6月1日 11:37
  • 多谢提示,

    老师说,我也就刚知道子窗体和父窗体的概念,看来要学习了。还有,这个数组包括父窗体本身吗?

    谢谢

    不包括父窗体本身 父窗体通过Me就可以获得引用了撒
    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月1日 11:39
    版主
  • 你好!
         我详细解释一下啊!这个问题是这样的:

         一个类的成员(包括属性)可以分为两种:静态成员(用static关键字定义的)和非静态成员(也就是实例成员)
         访问静态成员必须使用类来访问:Form1.MyStaticMember
         而访问实例成员必须使用类的实例来访问:
         Dim fm2 As new Form2
         fm2.MyInstanceMember

         想要获得Type可以使用Type.GetType方法,至于集合可以根据具体需要来选择,一般列表,数组什么的都可以!
        
    周雪峰
    2009年6月1日 11:50
    版主
  • 谢谢两位的耐心,

    我还想多问一句,如果我没理解错的话,frm2是Form2的一个实例,在程序中我们也都是用这个实例(而不是Form2)来操作。这样就保证了这个实例的唯一性。

    但是为什么Form2.ShowDialog()也能调用Form2窗体?Form2不是一个类吗?
    2009年6月1日 12:36
  • 如果你的Form2是一个类,Form2.ShowDialog()不可能成功,编译是会报错:非静态成员。。。要求对象引用!
    周雪峰
    2009年6月1日 13:44
    版主
  • 谢谢两位的耐心,

    我还想多问一句,如果我没理解错的话,frm2是Form2的一个实例,在程序中我们也都是用这个实例(而不是Form2)来操作。这样就保证了这个实例的唯一性。

    但是为什么Form2.ShowDialog()也能调用Form2窗体?Form2不是一个类吗?
    在Vb中Shared修饰的类型或结构的属性或者方法表示此属性或方法是共享的,也就是说所有这个类的实例使用这个属性或者方法的时候都是调用的同一个存储位置,即其他实例成员都没这个属性或者方法的副本 这一点和C#是不同的哈 所以你调用Form2.ShowDialog也是可以的 也不会出现编译错误
    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月1日 14:07
    版主
  • 但是下边的代码能够调用Form2。Form2也就是我随便添加的一个窗体呀?
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Form2.ShowDialog()
        End Sub
    难道是我又有什么理解偏了? 如果掉用了添加的Form2是不是说明窗体不是类?可能是我把你说的“窗体的类型”理解的不对。你说的“窗体的类型”是Type 而不是Class。见笑了。



    2009年6月1日 14:09
  • Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    
    
          'Dim myform2 As Form2 = New Form2
          'myform2.MdiParent = Me
          'myform2.Show()
          Form2.MdiParent = Me
          Form2.Show()
    
    
    
    
       End Sub
    注释掉的和没注释掉的效果是一样的哈
    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月1日 14:10
    版主
  • 谢谢两位的耐心,

    我还想多问一句,如果我没理解错的话,frm2是Form2的一个实例,在程序中我们也都是用这个实例(而不是Form2)来操作。这样就保证了这个实例的唯一性。

    但是为什么Form2.ShowDialog()也能调用Form2窗体?Form2不是一个类吗?
    在Vb中Shared修饰的类型或结构的属性或者方法表示此属性或方法是共享的,也就是说所有这个类的实例使用这个属性或者方法的时候都是调用的同一个存储位置,即其他实例成员都没这个属性或者方法的副本这一点和C#是不同的哈 所以你调用Form2.ShowDialog也是可以的 也不会出现编译错误
    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    说得挺绕口的,但基本看明白了^_^。



       Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Form2.ShowDialog()
        End Sub
    
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Dim myform2 As Form2 = New Form2
            myform2.ShowDialog()
        End Sub

    比如果Form2上有一个TextBox。第一个方法能保留TextBox中的数据,而第二个方法不能在关闭Form2后仍然保留数据,也就是说失去了ShowDialog的意义(ShowDialog打开的窗体关闭后只是隐藏,好像是这么说的)。
    难道两个方法是调用了不同的实例?

    2009年6月1日 14:49
  • 个人觉得Form2.showDiaolog是调用的共享的 他的生命周期应该是会在主窗体关闭之前的
    而第二个通过应该在这个过程执行完后就被回收了因为是个局部变量
    我个人是这样理解的哈......
    不过很久没弄VB.Net的了 很多东西都搞忘了


    努力着就不会放弃!.net技术交流群 33083877http://hi.baidu.com/1987raymond
    2009年6月1日 15:08
    版主
  • 你好!
         我向朋友请教了这个问题,看来我上面的说法有误,实际上这两种写法都是被VB.NET支持的:
         第一种写法:
    Dim myform2 As Form2 = New Form2
    myform2.ShowDialog()
    
    

         这个没有太多解释的,只是自己实例化一个新的实例,然后调用ShowDialog();
        
         第二种写法:
    Form2.ShowDialog()
         这个比较有意思了,实际上仅仅是语法上的支持,在编译器看来,上面的代码相当于这行代码:
    MyProject.Forms.Form2.ShowDialog()
         Forms是一个集合类,Form2是这个类的一个属性,获取这个属性的时候在内部会实例化生成一个Form2的实例

    就如同你理解的,这两种写法使用的是不同的实例!
    他支持第二种语法实际上是为了兼容过去VB6的语法,在VB.NET下强烈推荐使用第一种写法!


    周雪峰
    2009年6月1日 15:15
    版主
  • 你好!
         我向朋友请教了这个问题,看来我上面的说法有误,实际上这两种写法都是被VB.NET支持的:
         第一种写法:
    Dim myform2 As Form2 = New Form2
    
    myform2.ShowDialog()
    
    
    
    
    
    

         这个没有太多解释的,只是自己实例化一个新的实例,然后调用ShowDialog();
        
         第二种写法:
    Form2.ShowDialog()
         这个比较有意思了,实际上仅仅是语法上的支持,在编译器看来,上面的代码相当于这行代码:
    MyProject.Forms.Form2.ShowDialog()
         Forms是一个集合类,Form2是这个类的一个属性,获取这个属性的时候在内部会实例化生成一个Form2的实例

    就如同你理解的,这两种写法使用的是不同的实例!
    他支持第二种语法实际上是为了兼容过去VB6的语法,在VB.NET下强烈推荐使用第一种写法!


    周雪峰

    的确是这样,书上也是写的用My.Forms.Form2.ShowDialog()。但是没注意过。

    地一个方法的问题是,如果关闭Form2后,它的控件的值就消失了,下次打开什么都没了。这个怎么解决呢?用My命名空间的方法是没这个问题的。
    2009年6月1日 15:39
  • 可以把想保存的值保存到配置文件里,下次显示窗体的时候度取这些值!
    周雪峰
    2009年6月1日 15:57
    版主
  • 多谢版主。

    我也查了查,问了问,好像可以这样:

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            My.Forms.Form2.ShowDialog()
        End Sub

        Dim myform2 As Form2 = New Form2
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            myform2.ShowDialog()
        End Sub
    以上两个是等效的。但是第二个方法不能用Show()因为变量是在Sub外声明的。
    2009年6月2日 0:48
  • 你的意思是说,这里myform2.Show()不可以吗?应该可以的啊!
        Dim myform2 As Form2 = New Form2
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            myform2.ShowDialog()
        End Sub
    周雪峰
    2009年6月2日 0:54
    版主
  • 你的意思是说,这里myform2.Show()不可以吗?应该可以的啊!
        Dim myform2 As Form2 = New Form2
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            myform2.ShowDialog()
        End Sub
    周雪峰

    我是说,这个方法不能用Show()。下边的代码是不能重复调用"Form2"的。
        Dim myform2 As Form2 = New Form2
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            myform2.Show()
        End Sub
    注意这里的语句是myform2.Show()
    这是因为Show()和ShowDialog()是不一样的,一个是删除实例,一个是隐藏。

    解决方法应该是:
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Dim myform2 As Form2 = New Form2
            myform2.Show()
        End Sub
    2009年6月2日 1:09