C#中通过父窗口调用子窗口的问题

原创 2007年09月18日 20:44: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# WinForm 在父窗体与子窗体之间互相调用变量或方法

【父窗体调用子窗体变量或方法】:         首先在父窗体下定义子窗体,如:SubForm subform1=new SubForm();         再将子窗体subform1中需要调用的变...

C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)

本文转载:http://www.csframework.com/archive/2/arc-2-20110805-1771.htm 文章侧重点主要是讨论“窗体”与“窗体”之间方法的调用,以及“MDI...

C#在父窗口中调用子窗口的过程(无法访问已释放的对象)

来自:http://www.yiwuya.com/post/259.html C#在父窗口中调用子窗口的过程: 1、 创建子窗口对象 2、 显示子窗口对象 笔者的程序中,主窗体MainFrm通过菜单调...

JS子窗口调用父窗口

  • 2014-12-24 08:54
  • 877B
  • 下载

浏览器子窗口往父窗口传值遇到的window.opener is null 的问题

在做项目的时候遇到这样一个需求。 客户使用系统进行短信发送,可以通过选择数据库中的名片来添加收信人到一个列表框。我的想法是点击“选择名片”按钮,打开一个子窗口,子窗口为一个框架网页。分为左右两个框。...

子窗口和父窗口之间的数据交换问题

近来在编一个

子窗口最大化后在父窗口中以TabControl中显示的问题

要实现子窗口最大化后在父窗口中以TabControl中显示的问题首先要实现子窗口中调用父窗口控件的问题 第一步:创建form1窗体,在窗体form1中添加一个menuScript控件和TabCont...

子窗口调用父窗口变量和函数示例

示例1:子窗口是新打开的窗口   父窗口: parent var parentPara='parent'; function parentFuncti...

iframe 父窗口和子窗口相互的调用方法集锦

一、父窗口调用iframe子窗口方法  1、HTML语法:  2、父窗口调用子窗口:myFrame.window.functionName();  3、子窗品调用父窗口:parent.funct...

iframe 父窗口和子窗口相互的调用方法集锦 .

iframe 父窗口和子窗口相互的调用方法集锦 一、父窗口调用iframe子窗口方法 1、HTML语法: 2、父窗口调用子窗口:myFrame.window.functionName(); 3...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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