Form activeChild = this.ActiveMdiChild;
if (activeChild != null)
{
while (activeChild != null)
{
activeChild.Close();
activeChild.Dispose();
activeChild = this.ActiveMdiChild;
}
}
这里把所有的子窗体关闭了
然后再点击某个按钮,显示某个子窗体:
if (FORM2 == null)
{
FORM2 = new form2();
FORM2.MdiParent = this;
FORM2.Show();
}
else
{
FORM2.Activate();
FORM2.TopMost = true;
}
这里问题来了:在判断if (FORM2 == null) 的时候,为false,直接执行Else了。
我跟踪代码,在activeChild.Dispose();执行后,activeChild 和 this.ActiveMdiChild 都为null了,但是FORM2还是存在的。这样就导致了后面的判断不为null。
那么我想问一下,应该在哪里设置FORM2为null?可以在form2的Closed事件中设置吗?好像没办法写这个语句啊?
5 个解决方案
#1
#region MDI子窗体实例化一次
/// <summary>
/// 名称:CheckChildOpenState
/// 功能:用子窗体的Name进行判断是否已实例化,如果存在则将他激活
/// </summary>
/// <param name="MdiForm">容器窗体</param>
/// <param name="ChildForm">子窗体</param>
public static void CheckChildOpenState(Form MdiForm, Form ChildForm)
{
foreach (Form tempChildForm in MdiForm.MdiChildren)
{
if (tempChildForm.Name == ChildForm.Name.ToString())
{
if (tempChildForm.WindowState == FormWindowState.Minimized)
{
tempChildForm.WindowState = FormWindowState.Normal;
}
tempChildForm.Activate();
return;
}
}
ChildForm.MdiParent = MdiForm;
ChildForm.Show();
}
#endregion
#2
谢谢楼上的回复,我的问题不是这样的
主窗体上有很多按钮,“首页”按钮对应着主窗体的显示,其他按钮分别对应各个子窗体。
点击某个子窗体的按钮,即Load某个子窗体并显示它。
点击首页按钮,则关闭所有子窗体,并显示主窗体。
我现在遇到的问题是:在首页按钮的事件中,把所有的子窗体都CLose了。
然后点击某个子窗体按钮时,执行if (FORM2 == null) 语句,判断该子窗体是否为null,按道理前面CLose了,这里应该是null,但是我这里的代码执行判断为false,FORM2不为null。
如果在VB6里面,可以在FORM2的Close事件里:set form2 = nothing。
C#里面好像不能这么写,所以想问问,应该怎么写?
主窗体上有很多按钮,“首页”按钮对应着主窗体的显示,其他按钮分别对应各个子窗体。
点击某个子窗体的按钮,即Load某个子窗体并显示它。
点击首页按钮,则关闭所有子窗体,并显示主窗体。
我现在遇到的问题是:在首页按钮的事件中,把所有的子窗体都CLose了。
然后点击某个子窗体按钮时,执行if (FORM2 == null) 语句,判断该子窗体是否为null,按道理前面CLose了,这里应该是null,但是我这里的代码执行判断为false,FORM2不为null。
如果在VB6里面,可以在FORM2的Close事件里:set form2 = nothing。
C#里面好像不能这么写,所以想问问,应该怎么写?
#3
上面的方法你变通一下,单独加个判断即可。
如:给方法加个参数,来判断是否是单击的首页按钮,如true:关闭所有的子窗体,false:执行方法体即可。
public static void CheckChildOpenState(Form MdiForm, Form ChildForm)
{
if(false) foreach (Form tempChildForm in MdiForm.MdiChildren)
{
if (tempChildForm.Name == ChildForm.Name.ToString())
{
if (tempChildForm.WindowState == FormWindowState.Minimized)
{
tempChildForm.WindowState = FormWindowState.Normal;
}
tempChildForm.Activate();
return;
}
}
ChildForm.MdiParent = MdiForm;
ChildForm.Show();
else{关闭所有子窗体} }
如:给方法加个参数,来判断是否是单击的首页按钮,如true:关闭所有的子窗体,false:执行方法体即可。
public static void CheckChildOpenState(Form MdiForm, Form ChildForm)
{
if(false) foreach (Form tempChildForm in MdiForm.MdiChildren)
{
if (tempChildForm.Name == ChildForm.Name.ToString())
{
if (tempChildForm.WindowState == FormWindowState.Minimized)
{
tempChildForm.WindowState = FormWindowState.Normal;
}
tempChildForm.Activate();
return;
}
}
ChildForm.MdiParent = MdiForm;
ChildForm.Show();
else{关闭所有子窗体} }
#4
嗯,谢谢,我再问个问题:
我希望执行这么一条语句:ChildForm = null;
这条语句应该不能像VB那样,直接写在 ChildForm的close事件中吧?是不是也没法写在ChildForm里面呢?
如果不能写在ChildForm里面,那么是不是需要通过委托的方式,写在主窗体里面呢?
我希望执行这么一条语句:ChildForm = null;
这条语句应该不能像VB那样,直接写在 ChildForm的close事件中吧?是不是也没法写在ChildForm里面呢?
如果不能写在ChildForm里面,那么是不是需要通过委托的方式,写在主窗体里面呢?
#5
找到答案了,同时也谢谢楼上的朋友的帮助,我把答案贴这里,希望对大家有帮助:
如果不用MDI来实现一个主窗体打开多个子窗体时,
从一个窗体(主窗体)打开一个(only one) 另外一个的窗体(子窗体)的实现
父窗体:MainForm
public partial class MainForm:Form
{
............
private void menuItem1_Load(object sender,EventArgs e)
{
ChildForm child1=ChildForm.Create();
child1.show();
child1.Focus();
}
//......
}
子窗体:ChildForm
public partial class ChildForm:Form
{
.....
static ChildForm child;
Public static ChildForm Create()
{
if(child==null)
child=new ChildForm();
return Child;
}
......
}
F5运行后,的确实现了上面提到的功能。然而,把子窗体关闭后,想再次打开该子窗体时,单击菜单项,会出现异常:ObjectDisposedException was unhandled.
这是为什么呢??
这里涉及到C#垃圾回收的问题:
垃圾回收是.NET运行库的一部分。垃圾回收器管理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的垃圾回收器的制约。垃圾回收器可以确定运行垃圾回收的最佳时间,自动进行垃圾回收。然而垃圾回收的一个产物是:C# 对象没有确定性毁坏。所以会出现对象child已被销毁,但又不为null,访问时产生ObjectDisposedException异常。
怎么办??
方法:应该彻底回收Child所占的资源。
途径有二:
方法一:
修改子窗体的构造函数
public ChildForm()
{
//.........
this.Disposed+=new System.EventHandler(Form_Disposed)
}
然后事件Form_Disposed的处理函数
private void Form_Disposed(object sender,EventArgs e)
{
Child=null;
}
方法二:
重写ChildForm的OnClosed方法
Protected void OnClosed(EventArgs e)
{
base.OnClosed(e);
child=null;
}
当然可能有其他的方法,各位看客有兴趣的话补充一下。另外有叙述不当的地方,请多多指教,在下感激不尽。
如果不用MDI来实现一个主窗体打开多个子窗体时,
从一个窗体(主窗体)打开一个(only one) 另外一个的窗体(子窗体)的实现
父窗体:MainForm
public partial class MainForm:Form
{
............
private void menuItem1_Load(object sender,EventArgs e)
{
ChildForm child1=ChildForm.Create();
child1.show();
child1.Focus();
}
//......
}
子窗体:ChildForm
public partial class ChildForm:Form
{
.....
static ChildForm child;
Public static ChildForm Create()
{
if(child==null)
child=new ChildForm();
return Child;
}
......
}
F5运行后,的确实现了上面提到的功能。然而,把子窗体关闭后,想再次打开该子窗体时,单击菜单项,会出现异常:ObjectDisposedException was unhandled.
这是为什么呢??
这里涉及到C#垃圾回收的问题:
垃圾回收是.NET运行库的一部分。垃圾回收器管理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的垃圾回收器的制约。垃圾回收器可以确定运行垃圾回收的最佳时间,自动进行垃圾回收。然而垃圾回收的一个产物是:C# 对象没有确定性毁坏。所以会出现对象child已被销毁,但又不为null,访问时产生ObjectDisposedException异常。
怎么办??
方法:应该彻底回收Child所占的资源。
途径有二:
方法一:
修改子窗体的构造函数
public ChildForm()
{
//.........
this.Disposed+=new System.EventHandler(Form_Disposed)
}
然后事件Form_Disposed的处理函数
private void Form_Disposed(object sender,EventArgs e)
{
Child=null;
}
方法二:
重写ChildForm的OnClosed方法
Protected void OnClosed(EventArgs e)
{
base.OnClosed(e);
child=null;
}
当然可能有其他的方法,各位看客有兴趣的话补充一下。另外有叙述不当的地方,请多多指教,在下感激不尽。
#1
#region MDI子窗体实例化一次
/// <summary>
/// 名称:CheckChildOpenState
/// 功能:用子窗体的Name进行判断是否已实例化,如果存在则将他激活
/// </summary>
/// <param name="MdiForm">容器窗体</param>
/// <param name="ChildForm">子窗体</param>
public static void CheckChildOpenState(Form MdiForm, Form ChildForm)
{
foreach (Form tempChildForm in MdiForm.MdiChildren)
{
if (tempChildForm.Name == ChildForm.Name.ToString())
{
if (tempChildForm.WindowState == FormWindowState.Minimized)
{
tempChildForm.WindowState = FormWindowState.Normal;
}
tempChildForm.Activate();
return;
}
}
ChildForm.MdiParent = MdiForm;
ChildForm.Show();
}
#endregion
#2
谢谢楼上的回复,我的问题不是这样的
主窗体上有很多按钮,“首页”按钮对应着主窗体的显示,其他按钮分别对应各个子窗体。
点击某个子窗体的按钮,即Load某个子窗体并显示它。
点击首页按钮,则关闭所有子窗体,并显示主窗体。
我现在遇到的问题是:在首页按钮的事件中,把所有的子窗体都CLose了。
然后点击某个子窗体按钮时,执行if (FORM2 == null) 语句,判断该子窗体是否为null,按道理前面CLose了,这里应该是null,但是我这里的代码执行判断为false,FORM2不为null。
如果在VB6里面,可以在FORM2的Close事件里:set form2 = nothing。
C#里面好像不能这么写,所以想问问,应该怎么写?
主窗体上有很多按钮,“首页”按钮对应着主窗体的显示,其他按钮分别对应各个子窗体。
点击某个子窗体的按钮,即Load某个子窗体并显示它。
点击首页按钮,则关闭所有子窗体,并显示主窗体。
我现在遇到的问题是:在首页按钮的事件中,把所有的子窗体都CLose了。
然后点击某个子窗体按钮时,执行if (FORM2 == null) 语句,判断该子窗体是否为null,按道理前面CLose了,这里应该是null,但是我这里的代码执行判断为false,FORM2不为null。
如果在VB6里面,可以在FORM2的Close事件里:set form2 = nothing。
C#里面好像不能这么写,所以想问问,应该怎么写?
#3
上面的方法你变通一下,单独加个判断即可。
如:给方法加个参数,来判断是否是单击的首页按钮,如true:关闭所有的子窗体,false:执行方法体即可。
public static void CheckChildOpenState(Form MdiForm, Form ChildForm)
{
if(false) foreach (Form tempChildForm in MdiForm.MdiChildren)
{
if (tempChildForm.Name == ChildForm.Name.ToString())
{
if (tempChildForm.WindowState == FormWindowState.Minimized)
{
tempChildForm.WindowState = FormWindowState.Normal;
}
tempChildForm.Activate();
return;
}
}
ChildForm.MdiParent = MdiForm;
ChildForm.Show();
else{关闭所有子窗体} }
如:给方法加个参数,来判断是否是单击的首页按钮,如true:关闭所有的子窗体,false:执行方法体即可。
public static void CheckChildOpenState(Form MdiForm, Form ChildForm)
{
if(false) foreach (Form tempChildForm in MdiForm.MdiChildren)
{
if (tempChildForm.Name == ChildForm.Name.ToString())
{
if (tempChildForm.WindowState == FormWindowState.Minimized)
{
tempChildForm.WindowState = FormWindowState.Normal;
}
tempChildForm.Activate();
return;
}
}
ChildForm.MdiParent = MdiForm;
ChildForm.Show();
else{关闭所有子窗体} }
#4
嗯,谢谢,我再问个问题:
我希望执行这么一条语句:ChildForm = null;
这条语句应该不能像VB那样,直接写在 ChildForm的close事件中吧?是不是也没法写在ChildForm里面呢?
如果不能写在ChildForm里面,那么是不是需要通过委托的方式,写在主窗体里面呢?
我希望执行这么一条语句:ChildForm = null;
这条语句应该不能像VB那样,直接写在 ChildForm的close事件中吧?是不是也没法写在ChildForm里面呢?
如果不能写在ChildForm里面,那么是不是需要通过委托的方式,写在主窗体里面呢?
#5
找到答案了,同时也谢谢楼上的朋友的帮助,我把答案贴这里,希望对大家有帮助:
如果不用MDI来实现一个主窗体打开多个子窗体时,
从一个窗体(主窗体)打开一个(only one) 另外一个的窗体(子窗体)的实现
父窗体:MainForm
public partial class MainForm:Form
{
............
private void menuItem1_Load(object sender,EventArgs e)
{
ChildForm child1=ChildForm.Create();
child1.show();
child1.Focus();
}
//......
}
子窗体:ChildForm
public partial class ChildForm:Form
{
.....
static ChildForm child;
Public static ChildForm Create()
{
if(child==null)
child=new ChildForm();
return Child;
}
......
}
F5运行后,的确实现了上面提到的功能。然而,把子窗体关闭后,想再次打开该子窗体时,单击菜单项,会出现异常:ObjectDisposedException was unhandled.
这是为什么呢??
这里涉及到C#垃圾回收的问题:
垃圾回收是.NET运行库的一部分。垃圾回收器管理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的垃圾回收器的制约。垃圾回收器可以确定运行垃圾回收的最佳时间,自动进行垃圾回收。然而垃圾回收的一个产物是:C# 对象没有确定性毁坏。所以会出现对象child已被销毁,但又不为null,访问时产生ObjectDisposedException异常。
怎么办??
方法:应该彻底回收Child所占的资源。
途径有二:
方法一:
修改子窗体的构造函数
public ChildForm()
{
//.........
this.Disposed+=new System.EventHandler(Form_Disposed)
}
然后事件Form_Disposed的处理函数
private void Form_Disposed(object sender,EventArgs e)
{
Child=null;
}
方法二:
重写ChildForm的OnClosed方法
Protected void OnClosed(EventArgs e)
{
base.OnClosed(e);
child=null;
}
当然可能有其他的方法,各位看客有兴趣的话补充一下。另外有叙述不当的地方,请多多指教,在下感激不尽。
如果不用MDI来实现一个主窗体打开多个子窗体时,
从一个窗体(主窗体)打开一个(only one) 另外一个的窗体(子窗体)的实现
父窗体:MainForm
public partial class MainForm:Form
{
............
private void menuItem1_Load(object sender,EventArgs e)
{
ChildForm child1=ChildForm.Create();
child1.show();
child1.Focus();
}
//......
}
子窗体:ChildForm
public partial class ChildForm:Form
{
.....
static ChildForm child;
Public static ChildForm Create()
{
if(child==null)
child=new ChildForm();
return Child;
}
......
}
F5运行后,的确实现了上面提到的功能。然而,把子窗体关闭后,想再次打开该子窗体时,单击菜单项,会出现异常:ObjectDisposedException was unhandled.
这是为什么呢??
这里涉及到C#垃圾回收的问题:
垃圾回收是.NET运行库的一部分。垃圾回收器管理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的垃圾回收器的制约。垃圾回收器可以确定运行垃圾回收的最佳时间,自动进行垃圾回收。然而垃圾回收的一个产物是:C# 对象没有确定性毁坏。所以会出现对象child已被销毁,但又不为null,访问时产生ObjectDisposedException异常。
怎么办??
方法:应该彻底回收Child所占的资源。
途径有二:
方法一:
修改子窗体的构造函数
public ChildForm()
{
//.........
this.Disposed+=new System.EventHandler(Form_Disposed)
}
然后事件Form_Disposed的处理函数
private void Form_Disposed(object sender,EventArgs e)
{
Child=null;
}
方法二:
重写ChildForm的OnClosed方法
Protected void OnClosed(EventArgs e)
{
base.OnClosed(e);
child=null;
}
当然可能有其他的方法,各位看客有兴趣的话补充一下。另外有叙述不当的地方,请多多指教,在下感激不尽。