正确隐藏所有者窗体 [英] Properly Hiding Owner Form

查看:233
本文介绍了正确隐藏所有者窗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码隐藏父(所有者)的形式,而子窗体处于打开状态。这段代码妥善处理有关问题,其中应用程序(简单,没有可见窗口)可在过渡失去焦点?



栏目主要形式

 使用系统;使用System.Windows.Forms的
;

命名空间multiForms
{
公共部分类mainFrm:表
{
公共mainFrm()
{
的InitializeComponent() ;

this.button1.Click + =新System.EventHandler(this.button1_Click);
}

私人无效的button1_Click(对象发件人,EventArgs五)
{
childFrm子窗体=新childFrm();
subForm.ShowDialog(本);
subForm.Dispose();
}

}
}



部分子窗体:

 使用系统;使用System.Windows.Forms的
;

命名空间multiForms
{
公共部分类childFrm:表
{
公共childFrm()
{
的InitializeComponent() ;

this.Shown + =新System.EventHandler(this.childFrm_Shown);
this.FormClosing + =新System.Windows.Forms.FormClosingEventHandler(this.childFrm_FormClosing);
}

私人无效childFrm_Shown(对象发件人,EventArgs五)
{
this.Owner.Hide();
}

私人无效childFrm_FormClosing(对象发件人,FormClosingEventArgs E)
{
this.Owner.Show();
}

}
}


解决方案

这将正常工作。



但是,由于它在技术上并不正确。该事件的FormClosing可以取消,这可能不完全在你的控制,因为任何代码都可以写的事件的事件处理程序和e.Cancel属性设置为的真正的。在这样的情况下,它获取停止依靠事件是重要的。弹性的代码覆盖触发该事件,而不是方法。对于每一个XXXX的事件有,你可以覆盖相应的虚拟OnXxxx()方法。



在这种情况下,这样的方法重写应该是这样的:

 保护覆盖无效OnFormClosing(FormClosingEventArgs E){
base.OnFormClosing(E);
如果(e.Cancel&安培;!&安培;!this.Owner = NULL)this.Owner.Show();
}

现在它工作正常。如果没有的任何的代码周围订阅的FormClosing并取消它,那么你就不会显示主人。



请注意覆盖如何给你三种不同的东西可供选择,你可以这样做:




  • 您可以致电base.OnXxxx()首先,让你在控制
  • 您让您的修改,然后调用base.OnXxxx(),留下其他代码的控制。通常情况下,正确的选择,只是没有在此特定情况。但是,你如果你使用例如显示哪些常见的你想保存更改的消息框。您触发事件,如果用户点击取消,那么你不希望在所有触发事件之前,它应该被显示出来。

  • 您可能根本不叫base.OnXxxx() ,你这样做只有当你高度定制的事件处理,并允许该事件仍火容易打破程序。非常罕见的。



请注意感觉很好写这样的事件处理代码的因素。一类聆听到它的的事件并没有太大的意义。活动旨在为外部代码。就像在业主,在这个真正属于的代码。这恰好是在编程的WinForms常见,因为设计人员可以很容易地添加事件处理程序,它VB6的事件模型,编程工具的WinForms是为了替换匹配。它仍然是很容易写的OnXxxx()方法重写,智能感知支持很好。只需键入关于保护覆盖,并自动完成从那里。这是正确的方式OOPy


The following code hides the parent (Owner) form while the child form is open. Does this code properly handle the issue where the application (briefly with no visible windows) may lose focus in the transition?

Section Main Form

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();
        }

    }
}

Section Child Form:

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();
        }

    }
}

解决方案

It will work fine.

It is not technically correct however. The FormClosing event can be cancelled, it may not be completely under your control since any code can write an event handler for the event and set the e.Cancel property to true. In circumstances like this it gets to be important to stop relying on events. Resilient code overrides the method that fires the event instead. For every Xxxx event there's a corresponding virtual OnXxxx() method that you can override.

In this case, such a method override should like this:

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

Now it works fine. If there is any code around that subscribes FormClosing and cancels it then you won't show the owner.

Do note how the override gives you a choice of three different things you can do:

  • You can call base.OnXxxx() first, that leaves you in control.
  • You make your modification, then call base.OnXxxx(), that leaves the other code in control. Normally the correct choice, just not in this specific case. But what you use if you for example display the common "Do you want to save changes" message box. It should be displayed before you fire the event and if the user clicks Cancel then you don't want to fire the event at all.
  • You may not call base.OnXxxx() at all, you do so only if you heavily customized the event handling and allowing the event to still fire is liable to break the program. Pretty rare.

Do note the "feels good" factor of writing event handling code like this. A class listening to its own events doesn't make much sense. Events are meant for external code. Like the code in the Owner, where this really belongs. It just happens to be common in Winforms programming because the designer makes it easy to add event handlers and it matches the VB6 eventing model, the programming tool that Winforms was meant to replace. It is still very easy to write the OnXxxx() method override, IntelliSense supports it well. Just type "protected override on" and auto-complete from there. It is the correct OOPy way.

这篇关于正确隐藏所有者窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆