WinForm窗体应用——父窗体每次只打开一个子窗体的方法
![](https://img2023.cnblogs.com/blog/1308641/202212/1308641-20221213140207983-1329711891.png)
第一种方案:
private void btnOpenChildFrm_Click(object sender, EventArgs e) { ChildFrm childFrm = new ChildFrm(); childFrm.Show(); }
这种方法的可以实现子窗体的打开,但是每次点击按钮都可以打开一个子窗体。
我们有时候需要的是这样一种情况:
点击按钮打开一个子窗体,如果子窗体已经打开,则不再创建子窗体。也就是说只能打开一个子窗体,不能重复打开多个子窗体。
第二种方案:
ChildFrm childFrm = null; private void btnOpenChildFrm_Click(object sender, EventArgs e) { if (childFrm != null) { childFrm.Show(); } else { childFrm = new ChildFrm(); childFrm.Show(); } }
这样做,当打开一个子窗体后,在不关闭子窗体的情况下,再次点击“打开子窗体”按钮,不会再重新打开子窗体。
但是当子窗体关闭后,再点击“打开子窗体”按钮发生报错。错误信息如下:
这就让人奇怪了。如果子窗口没有被销毁,那它就应该能够正确显示。点击了关闭子窗口,显然应该子窗口已经销毁了,按理ChildFrm等于null,运行的时候应该直接运行else后面的语句块,为什么却进入了满足myChildFrm!=null的语句块呢?
这里有两个概念,一个是窗体类对象,一个是窗体类对象控制的windows 窗口。
窗体类封装了对 windows 窗口的操作,比如show()显示窗口,close() 关闭窗口。
所以当使用 close() 关闭窗口,其实是销毁并释放了 windows 窗口相关的资源。而控制这个 window 窗口的窗口类对象还是存在的,类对象中的变量还是与普通类对象一样,没有什么特别的。
这里报错的问题主要是,ChildFrm已经关闭且回收,但是ChildFrm并不等于Null的问题。解决方法如下:
ChildFrm childFrm = null; private void btnOpenChildFrm_Click(object sender, EventArgs e) { if (childFrm != null) { if (childFrm.IsDisposed) { childFrm = new ChildFrm(); } childFrm.Show(); } else { childFrm = new ChildFrm(); childFrm.Show(); } }
将两个if语句也做一下简化,如下:
ChildFrm childFrm = null; private void btnOpenChildFrm_Click(object sender, EventArgs e) { if (childFrm == null || childFrm.IsDisposed) { childFrm = new ChildFrm(); childFrm.Show(); } else { childFrm.Show(); } }
这里提供另一种方法,参考罗分明的博客,地址:winForm 窗体单例 (底层显示到上层,任务栏显示出来)-罗分明网络博客 (luofenming.com)
原理和上面的方法差不多,具体代码如下:
ChildFrm childFrm = null; private void btnOpenChildFrm_Click(object sender, EventArgs e) { if (childFrm == null || string .IsNullOrEmpty(childFrm.Text)) { childFrm = new ChildFrm(); childFrm.Show(); } else { childFrm.WindowState = FormWindowState.Normal; childFrm.BringToFront(); } }
这里给大家推荐一下,如果是搞C#开发,可以多关注一下罗分明的博客,有很多实用的案例和技巧。