C#在父窗口中调用子窗口的过程

转载 2007年09月24日 09:43:00
C#在父窗口中调用子窗口的过程:
1、 创建子窗口对象
2、 显示子窗口对象
 
笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm。在窗体中定义了子窗口对象,然后在菜单项点击事件中,加入了如下代码来创建和显示子窗口:
Private childFrm myChildFrm = null//定义子窗口对象
private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e)
...{
        myChildFrm 
= new ChildFrm();//创建子窗口对象
        myChildFrm.Show();//显示子窗口
        myChildFrm.Focus();//使子窗口获得焦点
}
当点击菜单中的OpenChild项时,创建了子窗口并显示在最前面。此时如果关闭子窗口再点击菜单打开,不会有问题。但是如果子窗口没有关闭的情况下,再次点击菜单中的OpenChild项,则会再创建一个子窗口。两个子窗口具有相同的内容,这不是我们所希望看到的。
为此,对菜单项点击事件做如下改进:
private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e)
...{
    
if(myChildFrm != null)
    
...{
        myChildFrm.Show();
//显示子窗口
        myChildFrm.Focus();//使子窗口获得焦点
    }

    
else
    
...{
        myChildFrm 
= new ChildFrm();//创建子窗口对象
        myChildFrm.Show();//显示子窗口
        myChildFrm.Focus();//使子窗口获得焦点
    }

}

这样修改的目的是:当子窗口对象存在时,直接显示子窗口。当子窗口不存在时,创建子窗口,然后再显示。
现在来检验效果:当第一次点击OpenChild菜单项时,创建子窗口并正确显示。不关闭子窗口的情况下再点击OpenChild菜单项,子窗口只显示了一个,说明按预期工作了。现在,我们关闭子窗口,再点击OpenChild菜单项,程序在运行到下面这个语句时出现“未处理 ObjectDisposedException”异常。
if(myChildFrm != null)
{
    myChildFrm.Show();//显示子窗口
错误信息:无法访问已释放的对象。对象名:“childFrm”。
这就让人奇怪了。如果子窗口没有被销毁,那它就应该能够正确显示。点击了关闭子窗口,显然应该子窗口已经销毁了,按理myChildFrm等于null,运行的时候应该直接运行else后面的语句块,为什么却进入了满足myChildFrm!=null的语句块呢?
其实,这个问题与C#的垃圾回收有关。垃圾回收器管理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的垃圾回收器的制约。垃圾回收器可以确定运行垃圾回收的最佳时间,自动进行垃圾回收。然而垃圾回收的一个产物是:C#对象没有确定性毁坏。所以会出现子窗口对象已被销毁,但又不为null,故出现访问时产生“未处理 ObjectDisposedException”异常(来自于“从小处看C#.net垃圾回收”一文)。
如何解决这个题,有人提出:应该应该彻底回收Child所占的资源。并提供了解决方法(请搜索“从小处看C#.net垃圾回收”查看相关情况)。
其实,现在我们需要解决的问题仅仅是:子窗口已经被销毁,但对象却不为null。只需要对你窗口中的菜单点击事件函数进行简单修改就可以了。
private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e)
...{
    
if(myChildFrm != null)
    
...{
          
if(myChildFrm.IsDisposed)
                  myChildFrm 
= new ChildFrm();//
如果已经销毁,则重新创建子窗口对象
          myChildFrm.Show();
          myChildFrm.Focus();
     }

    
else
    
...{
        myChildFrm 
= new ChildFrm();
        myChildFrm.Show();
        myChildFrm.Focus();
    }

}

前面这是按逻辑的方式进行思考的,显示子窗口和获得焦点两行是重复的,两个if语句也可以做一下简化。指定子窗口和父窗口的父子关系。最后的结果是这样:
private void OpenChildFrmToolStripMenuItem_Click(object sender, EventArgs e)
...{
    
if(myChildFrm == null || myChildFrm.IsDisposed)
    
...{  
        myChildFrm 
= new ChildFrm();
    }

    myChild..MdiParent = this; //建立父子关系

        myChildFrm.Show(); //显示子窗口
    myChildFrm.Focus();  //子窗口获得焦点
}
这样,就能够如我们如愿般调用子窗口了。
 

【C#】C#实现嵌入式窗体(弹出的子窗体在父窗体内)

最近有些时间,就把上半年做的东西整理了一下。   C#搭配SQL Server使用,是我们在学习数据库的时候比较好的工具。       由于换了一台电脑,以前的数据库也没有备份,所以现在无法运行。...
  • qq_32353771
  • qq_32353771
  • 2016年11月15日 21:20
  • 2149

子窗体和父窗体双向传值——C#窗体传值方法总结

简介  在很多场景下,我们的程序需要完成窗体间的传值功能,有时候是父窗体→子窗体单向传值、子窗体→父窗体传值甚至是,也有时候我们需要父窗体⇆子窗体双向传值。   在本文中主要介绍一些能够实现双向传值...
  • honantic
  • honantic
  • 2015年05月29日 11:54
  • 3534

C#子窗口与父窗口交互(使用委托和事件)

目标:在子窗口Form2上单击按钮时向Form1传递一组自定义参数,并显示在父窗口Form1上。 方法:有很多方法,这里只介绍委托和事件的实现方式。 思路:Form2中定义事件,Form1...
  • white__cat
  • white__cat
  • 2014年11月10日 11:02
  • 2260

c# 【委托】子窗体调用父窗体控件实例

原文地址:http://blog.csdn.net/chazikai24/article/details/5855254 下述代码,实现效果为:运行程序,点击form1的button1,弹出form...
  • lab2013
  • lab2013
  • 2013年03月08日 09:32
  • 1003

c#经典编程实例(六定时器Timer和工具条和父窗体和子窗体的创建)

一:首先先看一个简单的例子,就是倒计时 在工具箱中 的组件中选取Timer点击设置,重点是enable的设置 代码如下: int n = 10; priva...
  • zxq1138634642
  • zxq1138634642
  • 2013年06月15日 21:25
  • 3967

Qt 代码: 子窗口调用父窗口

之前的 Qt 编程大多只涉及简单的多窗口,并未染指窗口间的传值交互,想来还是“涉世未深”,对 Qt 的理解、应用还需殷勤努力。 这次的问题是这样的,我想要实现一个类似QQ...
  • u010398707
  • u010398707
  • 2014年08月31日 03:57
  • 2036

Qt 子窗口父窗口切换,窗口间传值

本人代码 win_win.pro 文件 #------------------------------------------------- # # Project created by QtCrea...
  • u013378306
  • u013378306
  • 2016年09月04日 14:27
  • 15511

MFC Dialog子窗口大小随父窗口而能改变,控件随窗口大小而改变

1、为Dialog添加类,假定类名字:CMyDLG。并将属性中的style设置为:child 2、CMyDLG的头文件添加:    public: CWnd *m_pParent; virtual...
  • u010385646
  • u010385646
  • 2015年05月25日 15:45
  • 3488

Qt中子窗口访问父窗口的成员变量

这里说的父窗口成员变量指的是含有自定义类型的变量,比如包含自定义结构/类的容器类(如QVector),对于父窗口中int、string等常规成员,可通过直接传地址的办法进行访问,不复杂。 ...
  • MyLinChi
  • MyLinChi
  • 2017年03月11日 22:55
  • 1754

MFC如何在父窗口的指定位置创建子窗口,及border边框属性设置

MFC中添加新的对话框
  • u013174689
  • u013174689
  • 2014年06月29日 12:36
  • 5145
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#在父窗口中调用子窗口的过程
举报原因:
原因补充:

(最多只允许输入30个字)