堵住关闭按钮触发的风云,关闭子窗口而不释放子窗口对象的难点解决

By admin in 4858.com on 2019年3月25日

1 在主窗口中实例化子窗口

在主窗口中实例化子窗口,而不是在按钮中实例化子窗口对象。

Form2 f2 = new Form2();

在网上找来一些艺术,感觉还都没错,上边给出方式:

自个儿将由此本文向大家介绍添加”窗口关闭的晋升”的至极做法。

原文 C# Winform
拦截关闭按钮触发的轩然大波

2 通过按钮来显示主窗口

在按钮中供给贯彻的是窗口的来得

private void Config_Click(object sender, EventArgs e)
        {
            f2.Show();
        }

在线扫描相机的调剂进度中,供给开拓调节和测试界面来进展岗位的配备。调试达成后,一种常用的办法是将调试参数保存并在下次运转时加载。另一种简单方法是一贯利用该参数运维程序。因而,在后一种情状下,供给贯彻的功力是:尽管关闭调节和测试窗口,其窗口对象也不自由。除非其主窗口关闭,才销毁其调节窗口的对象。

在程序运营时,能够透过点击右上角的红叉,关闭一个窗体;也得以由此调用窗体的Close()方法关闭窗体。假若想在窗体关闭前向用户提供三个提醒框,幸免重庆大学音讯未被保存就倒闭,大家会如何是好吧?很多少人会想到在调用Close前投入消息框代码。但这几个做法是不健全的,因为Close方法是被调用的,你不知晓Close在会何处调用,而且你不容许随地都写新闻框语句。正确的做法却不是调用Close在此之前,而是调用Close“之后”

用户关闭软件时,软件一般会给“是或不是承认关闭”的提示。

3 关闭子窗口而不释放子窗口对象的艺术

经查询和实证,修改子窗口中Dispose(在子窗口设计器中寻找修改)的方法是可行的。更改如下:

protected override void Dispose(bool disposing)
        {
            Hide();
            //if (disposing && (components != null))
            //{
            //    components.Dispose();
            //}
            //base.Dispose(disposing);
        }

1 在主窗口中实例化子窗口

  在主窗口中实例化子窗口,而不是在按钮中实例化子窗口对象。

 Form2 f2 = new Form2();

是的的做法是拍卖Form的FormClosing事件:

平凡,大家把它写在FormClosing
事件中,假如鲜明关闭,就倒闭;不然把FormClosing伊芙ntArgs 的 Cancel
属性设置为 true,就撤除了该窗体的倒闭。

4 在父窗口关闭时销毁子窗口对象

堵住关闭按钮触发的风云,关闭子窗口而不释放子窗口对象的难点解决。出于须要在父窗口关闭是销毁子窗口对象,因而,在父窗口的倒闭动作FormClosed中添加调用子窗口f2的灭绝函数。

 private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            f2.Close();
        }  

子窗口类中增加的倒闭函数如下:

 public void Close()
        {

            this.Dispose();

        }

出处:


别的还有一种艺术:

子窗体定义一个委托,父窗体实例化子窗体时注册子窗体的信托事件(具体功用是促成父窗口的控件变化),子窗体关闭时调用事件措施。

父窗体

public void ShowPopWindow()
        {
            TestA sub = new TestA();
            sub.CloseWindow += new Action(sub_CloseWindow);
            sub.show();
        }

        void sub_CloseWindow()
        {
            //改变父窗体控件内容
        }

子窗体

public class TestA
    {
        public event Action CloseWindow;

        protected virtual void OnCloseWindow()
        {
            Action handler = CloseWindow;
            if (handler != null) handler();
        }

      //子窗体关闭事件
        private void CloseSubWindow()
        {
            OnCloseWindow();
        }
    }

出处:


据说地方的注脚,大家协调实现和谐的成效,作者的功效实在极粗略,就一行代码,释放财富,

Form2 fui = null;

private void button1_Click(object sender, EventArgs e)
        {
            if (fui == null)
                fui = new userUserInfo();
            fui.MdiParent = this;
            fui.FormClosed += delegate(object obj, FormClosedEventArgs arg) { fui = null; };
            fui.Show();
            fui.Activate();
        }

但需求小心,在 fui.FormClosed += delegate(object obj,
FormClosed伊夫ntArgs arg) { fui = null;
};中选用的参数,不要和按钮事件中参数名相同,注意参数冲突。

出处:

2 通过按钮来呈现主窗口

  在按钮中需求完结的是窗口的体现

private void Config_Click(object sender, EventArgs e)
        {
            f2.Show();
        }

public delegate void FormClosingEventHandler(object sender,
FormClosingEventArgs e);
public event FormClosingEventHandler FormClosing;

设若该窗体是主窗体,大家想在该窗体关闭时关闭全体应用程序,会遇上至少三种情景:

3 关闭子窗口而不释放子窗口对象的点子

经查询和实证,修改子窗口中Dispose的方法是可行的。更改如下:

 protected override void Dispose(bool disposing)
        {
            Hide();
            //if (disposing && (components != null))
            //{
            //    components.Dispose();
            //}
            //base.Dispose(disposing);
        }

Form实例被调用Close()方法后,不是当下销毁窗体而是新建FormClosing伊芙ntArgs实例e,作为参数发出FormClosing,在事件被处理完后,再自小编批评e.Cancel是或不是等于true,如果是true窗口废除销毁,假设为false继续销毁Form。由此大家得以经过拍卖FormClosing事件,在拍卖当中对e.Cancel进行赋值,就可直达窗体打消关闭,所以怎么前边强调”之后”。例如,前面说到的能够如此达成代码:

(1)该窗体同时是开发银行窗体,即它是应用程序中保有窗体的父类,则整个应用程序会被关闭。

4 在父窗口关闭时销毁子窗口对象

  由于须要在父窗口关闭是销毁子窗口对象,因而,在父窗口的闭馆动作FormClosed中添加调用子窗口f2的销毁函数。

 private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            f2.Close();
        }  

4858.com ,  子窗口类中添加的闭馆函数如下:

 public void Close()
        {

            this.Dispose();

        }

 

出处:

===================================================================================

此外还有一种艺术:

子窗体定义一个寄托,父窗体实例化子窗体时注册子窗体的嘱托事件(具体职能是兑现父窗口的控件变化),子窗体关闭时调用事件措施。

  

父窗体
public void ShowPopWindow()
        {
            TestA sub = new TestA();
            sub.CloseWindow += new Action(sub_CloseWindow);
            sub.show();
        }

        void sub_CloseWindow()
        {
            //改变父窗体控件内容
        }

子窗体
public class TestA
    {
        public event Action CloseWindow;

        protected virtual void OnCloseWindow()
        {
            Action handler = CloseWindow;
            if (handler != null) handler();
        }

      //子窗体关闭事件
        private void CloseSubWindow()
        {
            OnCloseWindow();
        }
    }

出处:

========================================================================

基于下边包车型地铁印证,大家本人落成自个儿的职能,笔者的职能实在很简单,就一行代码,释放能源,

Form2 fui = null;

private void button1_Click(object sender, EventArgs e)
        {
            if (fui == null)
                fui = new userUserInfo();
            fui.MdiParent = this;
            fui.FormClosed += delegate(object obj, FormClosedEventArgs arg) { fui = null; };
            fui.Show();
            fui.Activate();
        }

但供给留意,在 fui.FormClosed += delegate(object obj,
FormClosed伊夫ntArgs arg) { fui = null;
};中利用的参数,不要和按钮事件中参数名相同,注意参数争持。

 

(2)如若该窗体不是运维窗体,比如大家做了二个欢迎窗体,则应用程序中拥有窗体的父类就是其一欢迎窗体了。那时该窗体的关闭并不会倒闭全体应用程序。大家需求再进入“Application.Exit()”那行代码来退出应用程序。但与此同时又有标题了,父窗体的倒闭又会给该窗体发送关闭事件,于是该事件又被调用壹遍,确认对话框又会弹出第三遍。消除形式是用上面包车型大巴代码:


this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);

注:做欢迎体界面能够在主窗体中,ShowDialog方法打开欢迎界面,而不是把欢迎界面作为运营窗体。下边包车型大巴点子仅有理论意义。

 

        protected override void WndProc(ref Message m)
        {
            //Console.WriteLine(m.Msg);
            const int WM_SYSCOMMAND = 0x0112;
            const int SC_CLOSE = 0xF060;
            if (m.Msg == WM_SYSCOMMAND && (int)m.WParam == SC_CLOSE)
            {
                //捕捉关闭窗体消息 http://www.cnblogs.com/sosoft/
                //用户点击关闭窗体控制按钮   注释为最小化窗体   
                //this.WindowState = FormWindowState.Minimized;

                //窗体隐藏
                this.Hide();
                return;
            }
            base.WndProc(ref m);
        } 

void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (MessageBox.Show(
            “窗口关闭后,数据即将丢失!是或不是今后关闭窗口”,
            “提示”, 
            MessageBoxButtons.OKCancel, 
            MessageBoxIcon.Question) != DialogResult.OK)
            {
                e.Cancel = true;
            }
}

 

但要注意,这种处理程序一般的话唯有e.Cancel = true;的代码,没有e.Cancel =
false;的代码。因为事件是属于一种委托,委托是多播的。所以,有大概有五个事件处理代码段,假设赋值将会影响整个信托的参数。那里的急需是,一旦中间3个拍卖的代码段e.Cancel=true,窗体都不应该被关闭,所以应尽量幸免e.Cancel=false
的赋值语句影响其余的事件处理结果。

C# 窗体关闭时能够接触的事件

FormClosing :在窗体关闭时,FormClosing
事件时有产生。窗体关闭时,此事件会取得处理,从而释放与此窗体关联的保有能源。假如撤除此事件,则该窗体保持开拓状态。若要废除窗体的闭馆操作,请将传递给事件处理程序的
FormClosing伊芙ntArgs 的 Cancel 属性设置为 true。

FormClosed:在用户或 Application 类的 Close 方法或 Exit
方法关闭窗体后,会爆发 FormClosed 事件。若要防止窗体关闭,请处理
FormClosing 事件,并将传递给事件处理程序的 Cancel伊夫ntArgs 的 Cancel
属性设置为
true。能够采纳此事件实施一些任务,如自由窗体使用的财富,还可使用此事件保存输入窗体中的音信或更新其父窗体。

当窗体彰显为方式对话框时,单击“关闭”按钮(窗体右上角带 X
的按钮)会暗藏窗体并将 DialogResult 属性设置为
DialogResult.Cancel。通过在窗体的 FormClosing 事件的事件处理程序中设置
DialogResult 属性,能够在用户单击“关闭”按钮时重写分配给 DialogResult
属性的值。

注意
在显示为无方式窗口的 Form 上调用 Close 方法时,不能够调用 Show
方法使窗体可知,因为窗体的能源已被保释。若要隐藏窗体然后又使其可知,请使用
Hide 方法。
 

假定窗体是多文书档案界面 (MDI) 父窗体,则在引发 MDI 父窗体的 FormClosing
事件在此之前将吸引全数 MDI 子窗体的 FormClosing 事件。同样,在诱惑 MDI
父窗体的 FormClosed 事件此前,将掀起全部 MDI 子窗体的 FormClosed
事件。裁撤 MDI 子窗体的 FormClosing 事件不可能预防引发 MDI 父窗体的
FormClosing 事件。不过,撤除该事件会将用作参数字传送递给父窗体的
FormClosing伊夫ntArgs 类的 Cancel 属性设置成 false。要强制关闭全数 MDI
父窗体和子窗体,请将 MDI 父窗体中的 Cancel 属性设置成 false。

上边二个简易例子:

private void Form2_FormClosing(object sender, FormClosingEventArgs e)  
{  
    DialogResult result = MessageBox.Show("你确定要关闭吗!", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);  
    if (result == DialogResult.OK)  
    {  
        e.Cancel = false;  //点击OK
    }  
    else 
    {  
        e.Cancel = true;  
    }  
}

 推荐贰个C#操作SQL
Server数据库的实例:

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有