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#在父窗口中调用子窗口的过程(无法访问已释放的对象)的更多相关文章

  1. C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常,不存在从对象类型System.Windows.Forms.DateTimePicker到已知的托管提供程序本机类型的映射。

    一:C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常 其实,这个问题与C#的垃圾回收有关.垃圾回收器管 理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的 垃圾回收器 ...

  2. React Hooks中父组件中调用子组件方法

    React Hooks中父组件中调用子组件方法 使用到的hooks-- useImperativeHandle,useRef /* child子组件 */ // https://reactjs.org ...

  3. vue 父组件中调用子组件函数

    2019/06/06 在父组件中调用子组件的方法:  1.给子组件定义一个ref属性.eg:ref="childItem"  2.在子组件的methods中声明一个函数.eg: u ...

  4. vue组件之间的通信以及如何在父组件中调用子组件的方法和属性

    在Vue中组件实例之间的作用域是孤立的,以为不能直接在子组件上引用父组件的数据,同时父组件也不能直接使用子组件的数据 一.父组件利用props往子组件传输数据 父组件: <div> < ...

  5. AngularJs中,如何在父元素中调用子元素为自定义Directive中定义的函数?

    最近一段时间准备使用AngularJs中的自定义Directive重构一下代码. 在这里说明一下,把自定义控件封装成Directive并不一定是要复用,而是要让代码结构更加清晰.就好像你将一个长方法拆 ...

  6. vue父组件中调用子组件的方法

    Vue项目中如何在父组件中直接调用子组件的方法: 方案一:通过ref直接调用子组件的方法: //父组件中 <template> <div> <Button @click= ...

  7. C#中关闭子窗口而不释放子窗口对象的方法

    1 在主窗口中实例化子窗口 在主窗口中实例化子窗口,而不是在按钮中实例化子窗口对象. Form2 f2 = new Form2(); 2 通过按钮来显示主窗口 在按钮中需要实现的是窗口的显示 priv ...

  8. 项目总结03:window.open()方法用于子窗口数据回调至父窗口,即子窗口操作父窗口

    window.open()方法用于子窗口数据回调至父窗口,即子窗口操作父窗口 项目中经常遇到一个业务逻辑:在A窗口中打开B窗口,在B窗口中操作完以后关闭B窗口,同时自动刷新A窗口(或局部更新A窗口)( ...

  9. 父窗口和iframe子窗口之间相互传递参数和调用函数或方法

    1.父窗口向子窗口传递参数: 可以在url中添加参数:2.html?a=1&b=2&c=3 然后在子页面上可用js解析,提供一个函数: function getQueryStr(sAr ...

随机推荐

  1. cf B. Maximum Absurdity

    http://codeforces.com/contest/332/problem/B #include <cstdio> #include <cstring> #includ ...

  2. NGINX小技巧--将所有目录和目录下所有文件分别给与不同的权限

    为了安全,有时要将文件的权限进行限制,但,目录如果没有755,则不能进入. 所以需要分别给权限 find ./ -type f -name "*" |xargs ls -l

  3. 面试题 46 1+ 2+3+...+n

    class Temp{ public: Temp(){ ++N; sum+=N; } static void Reset(){ N = ; sum = ; } static int getSum(){ ...

  4. mysql sql优化<1>

    <pre name="code" class="html">explain SELECT t.* FROM ( SELECT t1.sn AS cl ...

  5. [转]Ubuntu Linux 安装 .7z 解压和压缩文件

    原文网址:http://blog.csdn.net/zqlovlg/article/details/8033456 安装方法: sudo apt-get install p7zip-full 解压文件 ...

  6. JS实现 鼠标放上去 图片自动放大的效果

    前段时间做项目,要实现,一张图片,鼠标放上去图片自动变大的效果,虽然难度不大,但当时也想了一段时间,当时没时间记录一下,现在有时间了,写篇博客把代码给记录一下: 效果如下: 代码如下: <!DO ...

  7. Hello Bolg!

    初来乍到,将就闹点小情绪吧 博客, 作为一个即将毕业的小码农, 第一次写这东西似乎生涩了点. 而且第一眼看到这东西还觉得特玄乎,不过“化抽象为具体, 化复杂为简单”不正是自己的职业操守吗. 于是, 我 ...

  8. VC青睐服装订制网站 市场规模超3000亿美元 - 找VC - 创业邦

    VC青睐服装订制网站 市场规模超3000亿美元 - 找VC - 创业邦 VC青睐服装订制网站 市场规模超3000亿美元

  9. PHP基础设计模式——工厂模式

    <?php//文件名:Factory namespace IMooc; class Factory { //工程模式 static function creatDatabase() { $db ...

  10. (转)iOS7界面设计规范(11) - UI基础 - 图标与图形

    不知别人如何,我自己来讲,平时很习惯很有动力去做的一些事,譬如博客吧,一旦生活中出现一些让自己很难受的状况,就很容易受到影响:像是,你平时所习惯的生活状态都是基于某种东西的,一旦这种东西崩塌,会影响到 ...