本文转载:http://www.cnblogs.com/Ricky81317/archive/2008/09/17/1292443.html

看到论坛中有朋友问,如何可以保证在MDI主窗体中,同一类型的子窗体只能打开一次,再打开只是将原来打开的窗体激活。这个要求我以前写程序的时候也遇到过。我实现的基本思路是:

一般每个子窗体都是继承自Form类型,不同子窗体分别代表不同的功能,因此只需要判断当前MDI打开的子窗体的类型中有没有当前需要打开的子窗体类型就行了,如果有,则直接激活,如果没有则创建一个并加到主窗体中。具体实现起来有很多种办法,这里只写出一个利用泛型的实现:

/// <summary>
/// 打开MDI子窗口并附加到MDI主窗口中,如果MDI主窗口中已经存在相同类型的子窗口,则直接激活
/// </summary>
/// <typeparam name="T">MDI子窗体类型</typeparam>
/// <param name="mdiParent">MDI主窗体引用</param>
/// <returns>当前创建或得到的MDI子窗体类型实例的引用</returns>
private T OpenUniqueMDIChildWindow<T>(Form mdiParent) where T : Form, new()
{
    foreach (Form subForm in mdiParent.MdiChildren)
    {
        if (subForm.GetType().Equals(typeof(T)))
        {
            subForm.Activate();
            return subForm as T;
        }
    }
    T newForm = new T();
    newForm.MdiParent = mdiParent;
    newForm.Show();
    return newForm;
}

这个方法可以放在你的菜单项的单击事件处理方法中。
比如你想单击About菜单项,打开一个AboutForm类型的窗体,那么就:
OpenUniqueMDIChildWindow<AboutForm>(this)
看代码的话,你会发现,如果About窗体已经被打开过的话,会自动激活那个窗体,如果没有,那么它会自己new一个出来,不需要你手工创建。

保证相同类型的MDI子窗体只会被打开一次的方法的更多相关文章

  1. Delphi中实现MDI子窗体(转)

        Delphi中实现MDI子窗体 用MDI实现浏览子窗口,具有窗口管理功能,同屏观看多个网页的内容  ① 多文档窗体(MDI) MDI窗体是一种具有主子结构的窗体体系,微软的Word便是其中的一 ...

  2. 用DLL方式封装MDI子窗体

    用DLL方式封装MDI子窗体是一种常用的软件研发技术,他的长处: 研发人员能够负责某一个模块的编写包括(界面+逻辑),能够互不干扰,模块研发完成后,主程式统一调用. 易于程式升级,当程式升级时,不用编 ...

  3. 解决WinForm(C#)中MDI子窗体最大化的问题

    “用MDI方式打开一个子窗口体后,总是不能最大化显示,明明子窗口体的WindowState设置为Maximized?”,相信有很多人会遇到这的样问题,请按下面的方法设置即可使MDI子窗体最大化: 1. ...

  4. 在DLL动态链接库中封装VCL的MDI子窗体

    在DLL动态链接库中封装VCL的MDI子窗体不多说了,看代码就应该明白了,曾经我遇到的问题,现在放出来大家共享! 这里是工程文件的部分: 在DLL中封装MDI子窗体需要重写DLL入口函数,具体代码如下 ...

  5. Delphi MDI 子窗体的创建和销毁 [zhuan]

    1.如果要创建一个mdi child,先看是否有这个child 存在,如果有,则用它,如果没有再创建 //该函数判断MDI 子窗体是否存在,再进行创建和显示function isInclude(for ...

  6. C# Winform 防止MDI子窗体重复打开

    可以在MDI主窗体中添加以下方法. //防止打开多个窗体 private bool ShowChildrenForm(string p_ChildrenFormText) { int i; //依次检 ...

  7. 解决WinForm(C#)中MDI子窗体最大化跑偏的问题

    “用MDI方式打开一个子窗口体后,总是不能最大化显示,明明子窗口体的WindowState设置为Maximized?”,相信有很多人会遇到这的样问题,请按下面的方法设置即可使MDI子窗体最大化: 1. ...

  8. DELPHI中MDI子窗口的关闭和打开

    DELPHI中MDI子窗口的关闭 和打开       Delphi中MDI子窗口的关闭方式默认为缩小而不是关闭,所以当你单击子窗口右上角的关闭按钮时会   发觉该子窗口只是最小化,而不是你预期的那样被 ...

  9. DELPHI中MDI子窗口的关闭 和打开

    Delphi中MDI子窗口的关闭方式默认为缩小而不是关闭,所以当你单击子窗口右上角的关闭按钮时会发觉该子窗口只是最小化,而不是你预期的那样被关闭.解决办法是在子窗口的OnClose事件处理过程中加入如 ...

随机推荐

  1. php函数的初步使用

    通过调用函数,实现打印半金字塔.全金字塔.空心金字塔.菱形.空心菱形 调用例程 huaTuMain.php 被调用函数 huaTu.php

  2. 17173php招聘

    学历要求:大专工作经历:4年↑薪资待遇:面议工作地点:北京市 资深PHP工程师岗位职责\\\"1.独立负责公司互联网产品的开发与测试2.主导负责相关系统维护,确保系统运行稳定可靠3.主导推动 ...

  3. VC杂记

    获得Combobox的状态:向ComboBox发送CB_GETDROPPEDSTATE消息. 格式化字串:char buff[10] ; sprintf(buff,"1+1=%d" ...

  4. awk 多分隔符

    #!/bin/bash log_path="./log/" dates=`date -d '-1 days' +'%Y%m%d'` cd $log_path; for i in ` ...

  5. Word 2016 test

    Word 2016 test    

  6. 编译u-boot命令和u-boot常用命令

    一.编译u-boot命令 1.配置开发板 #make TQ2440_config 2.编译 #make all 3.交叉编译器是crosstools_3.4.5_softfloat” 使用4.3.3版 ...

  7. C# this.Invoke()的作用和用法(摘)

    Invoke()的作用是:在应用程序的主线程上执行指定的委托.一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke();   在多线程编程中,我们经常要在工作线程 ...

  8. servlet跳转jsp

    ackage com.monkey.servlet; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; im ...

  9. Socket理解

    简介 本文主要介绍的socket编程的实现相关的内容: 理论 函数 socket 用来创建socket描述符,它唯一标识一个socket int socket(int domain, int type ...

  10. 自定义UICollectionViewController之后 如何设置UICollectionView的布局方式--备用

    我们很多时候使用UICollectionView 可能都是直接创建 UICollectionView   通过初始化的时候  传入一个布局对象的方式来使用UICollectionView 比如我们之前 ...