正确隐藏所有者表格

本文关键字:所有者 表格 隐藏所 隐藏 | 更新日期: 2023-09-27 18:00:25

以下代码在子窗体打开时隐藏父窗体(Owner)。此代码是否正确处理了应用程序(短暂地没有可见窗口)可能在转换中失去焦点的问题?

分区主窗体

using System;
using System.Windows.Forms;
namespace multiForms
{
    public partial class mainFrm : Form
    {
        public mainFrm()
        {
            InitializeComponent();
            this.button1.Click += new System.EventHandler(this.button1_Click);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            childFrm subForm = new childFrm();
            subForm.ShowDialog(this);
            subForm.Dispose();
        }
    }
}

子窗体部分:

using System;
using System.Windows.Forms;
namespace multiForms
{
    public partial class childFrm : Form
    {
        public childFrm()
        {
            InitializeComponent();
            this.Shown += new System.EventHandler(this.childFrm_Shown);
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.childFrm_FormClosing);
        }
        private void childFrm_Shown(object sender, EventArgs e)
        {
            this.Owner.Hide();
        }
        private void childFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Owner.Show();
        }
    }
}

正确隐藏所有者表格

它会正常工作。

然而,这在技术上并不正确。FormClosing事件可以取消,它可能不完全在您的控制之下,因为任何代码都可以为该事件编写事件处理程序,并将e.Cancel属性设置为true。在这种情况下,停止依赖事件变得很重要。弹性代码替代了触发事件的方法。对于每个Xxxx事件,都有一个相应的虚拟OnXxxx()方法,您可以覆盖它。

在这种情况下,这样的方法覆盖应该是这样的:

    protected override void OnFormClosing(FormClosingEventArgs e) {
        base.OnFormClosing(e);
        if (!e.Cancel && this.Owner != null) this.Owner.Show();
    }

现在它运行良好。如果周围有任何代码订阅FormClosing并取消它,那么您将不会显示所有者。

请注意,覆盖如何让您可以选择三种不同的方法:

  • 你可以打电话给基地。首先是OnXxxx(),这让您可以控制
  • 您进行修改,然后呼叫基地。OnXxxx(),这让其他代码处于控制之中。通常是正确的选择,只是在这种特定情况下不是。但是,例如,如果显示常见的"Do you want to save changes"消息框,则会使用什么。它应该在您触发事件之前显示,如果用户单击"取消",则您根本不想触发事件
  • 你不能打电话给基地。在OnXxxx()上,只有当您对事件处理进行了大量定制,并且允许事件仍然激发时,才有可能破坏程序。非常罕见

请注意,编写这样的事件处理代码的"感觉良好"因素。一个类监听它自己的事件没有多大意义。事件用于外部代码。就像所有者中的代码一样,这才是真正的归属。它恰好在Winforms编程中很常见,因为设计器可以很容易地添加事件处理程序,并且它与Winforms要取代的编程工具VB6事件模型相匹配。编写OnXxxx()方法重写仍然很容易,IntelliSense很好地支持它。只需键入"protected override on",然后自动完成即可。这是正确的OOPy方式。