C#编程学习19:mdi窗体中子窗体不能重复打开的三种实现方式

简介: C#编程学习19:mdi窗体中子窗体不能重复打开的三种实现方式

需求描述:在MDI窗体中,子窗体只能被打开一次,如果已有窗体不会在重新创建窗体对象



1 窗体的创建

(1)创建mdi窗体:新建窗体将其名称更改为FormMain,属性IsMdiContainer设置为true


(2)创建子窗体1:新建窗体将其名称更改为childForm1


(3)创建子窗体1:新建窗体将其名称更改为childForm2


(4)增加菜单项tsmi_singleMode,其Text属性设置为单例模式子窗体


(5)增加菜单项tsmi_application,其Text属性设置为函数模式子窗体


(6)增加菜单项tsmi_foreach,其Text属性设置为函数模式子窗体


界面如下:

20190526003336562.png

2 单例模式的实现

(1)在子窗体1中将其构造函数改成private;添加静态成员和静态变量

//私有构造函数        
private childForm1()
        {
            InitializeComponent();
        }
//私有静态类类型的成员变量
        private static childForm1 inquire = null;
//公有静态类型成员函数
        public static childForm1 GetWindows()
        {
            if (inquire == null && inquire.IsDisposed)
            {
                inquire = new childForm1();
            }
            return inquire;            
        }

(2)父窗体MDI中的为tsmi_singleMode按钮添加Click事件:

        private void tsmi_singleMode_Click(object sender, EventArgs e)
        {
            childForm1 cf1 = childForm1.GetWindows();
            cf1.MdiParent = this;
            cf1.Show();
        }

3 函数模式之Application.OpenForms实现

使用Application.OpenForms来判断是否创建新的子窗体

//使用Application搜集已经打开的子窗体;若找不到就创建;找到则显示
private void tsmi_application_Click(object sender, EventArgs e)
        {
            foreach (Form frm in Application.OpenForms)            
            {
                if (frm is ChildForm2)
                {
                    frm.Activate();
                    frm.WindowState = FormWindowState.Normal;
                    return;
                }
            }
            ChildForm2 youForm = new ChildForm2();
            youForm.MdiParent = this;
            youForm.Show();
        }

4 函数模式实现之遍历this.MdiChildren子窗体实现

定义判断函数

 private void OpenChildForm(Form formChild)//formChild只是是实例化的但既没有设置为父窗体的子窗体也没有显示
        {
            bool isOpened = false;
            foreach (Form form in this.MdiChildren)
            {
                //如果要显示的子窗体已经在父窗体的子窗体数组数组中,我们就把新建的多余的formChild销毁
                if (formChild.Name == form.Name)
                {
                    form.Activate();//既然我们想新建但已经有了,那就把之前存在的激活并调到最前边来
                    form.WindowState = FormWindowState.Normal;//窗口大小  为窗口模式
                    formChild.Dispose();
                    isOpened = true;//表示窗口已经打开
                    break;
                }
            }
            if (!isOpened)//如果没打开
            {
                formChild.MdiParent = this;//设置为子窗体
                formChild.Show();
            }
        }

添加点击事件

private void tmsi_foreach_Click(object sender, EventArgs e)
        {
            childForm3 cf3 = new childForm3();
            cf3.Name = "childForm3";
            OpenChildForm(cf3);
        }

5 总结

列举了三种实现方式,第一种将类定义为私有构造函数、私有静态成员和公有静态成员的单例模式来实现;方法二遍历Application.OpenForms判断子窗体是否打开;方法三,遍历this.MdiChildren判断子窗体是否存在


相关文章
|
13天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
28 3
|
4天前
|
Java 物联网 C#
C#/.NET/.NET Core学习路线集合,学习不迷路!
C#/.NET/.NET Core学习路线集合,学习不迷路!
|
27天前
|
设计模式 程序员 C#
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
|
1月前
|
开发框架 缓存 算法
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
|
1月前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。
101 0
|
2月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
41 2
|
2月前
|
安全 程序员 编译器
C#一分钟浅谈:泛型编程基础
在现代软件开发中,泛型编程是一项关键技能,它使开发者能够编写类型安全且可重用的代码。C# 自 2.0 版本起支持泛型编程,本文将从基础概念入手,逐步深入探讨 C# 中的泛型,并通过具体实例帮助理解常见问题及其解决方法。泛型通过类型参数替代具体类型,提高了代码复用性和类型安全性,减少了运行时性能开销。文章详细介绍了如何定义泛型类和方法,并讨论了常见的易错点及解决方案,帮助读者更好地掌握这一技术。
74 11
|
2月前
|
SQL 开发框架 安全
并发集合与任务并行库:C#中的高效编程实践
在现代软件开发中,多核处理器普及使多线程编程成为提升性能的关键。然而,传统同步模型在高并发下易引发死锁等问题。为此,.NET Framework引入了任务并行库(TPL)和并发集合,简化并发编程并增强代码可维护性。并发集合允许多线程安全访问,如`ConcurrentQueue<T>`和`ConcurrentDictionary<TKey, TValue>`,有效避免数据不一致。TPL则通过`Task`类实现异步操作,提高开发效率。正确使用这些工具可显著提升程序性能,但也需注意任务取消和异常处理等常见问题。
48 1
|
1月前
|
API C# Windows
【C#】在winform中如何实现嵌入第三方软件窗体
【C#】在winform中如何实现嵌入第三方软件窗体
68 0
|
2月前
|
Linux C# 开发者
Uno Platform 驱动的跨平台应用开发:从零开始的全方位资源指南与定制化学习路径规划,助您轻松上手并精通 C# 与 XAML 编程技巧,打造高效多端一致用户体验的移动与桌面应用程序
【9月更文挑战第8天】Uno Platform 的社区资源与学习路径推荐旨在为初学者和开发者提供全面指南,涵盖官方文档、GitHub 仓库及社区支持,助您掌握使用 C# 和 XAML 创建跨平台原生 UI 的技能。从官网入门教程到进阶技巧,再到活跃社区如 Discord,本指南带领您逐步深入了解 Uno Platform,并提供实用示例代码,帮助您在 Windows、iOS、Android、macOS、Linux 和 WebAssembly 等平台上高效开发。建议先熟悉 C# 和 XAML 基础,然后实践官方教程,研究 GitHub 示例项目,并积极参与社区讨论,不断提升技能。
91 2