2010-05-10 88 views
7

这必须是一个愚蠢的问题,但我无法弄清楚。我也无法使用这个设计器,因为之前的编码器设法将GUI和逻辑全部集成在一起,所以现在它很混乱。我必须这样做旧的方式。.NET Windows窗体 - 拦截Close X事件

我有一个可以用3种方式关闭的窗体:关闭按钮,文件/关闭菜单和X图标。我希望他们都做同样的事情。拦截按钮和菜单事件很容易。实际上,两者都被连接到了一个onCloseConfig方法。顺便说一句,这个方法有更好的名字吗?

private void onCloseConfig(object sender, System.EventArgs e) 
{ 
    if (! m_configControl.Modified) 
    { 
     Application.Exit(); // Or should it be this.Close(); 
    } 
    .... 
    // Else present a dialog, ask if they want to save. 
} 

因此,拦截X我想:this.FormClosing +=new FormClosingEventHandler(this.onCloseConfig);我认为这是什么原因导致一个无限循环。我不想那个:) FormClosed是另一种选择,但它似乎为时已晚。我只想拦截X被点击的事实,而不是表单正在关闭的事实。

回答

12

我认为您确实希望表单关闭,您可能会忽略的是检查关闭的原因,并且只有在用户从用户那里取消时才会取消。

private void my_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if (e.CloseReason == CloseReason.UserClosing) 
    { 
    e.Cancel = true; //I'm sorry Dave, I'm afraid I can't do that. 
    } 
} 

隐藏的“X”设置Form.ControlBox = false,但是这将摆脱最小/最大的为好。

+0

Cool!有没有办法将X完全隐藏起来? – 2010-05-10 15:45:23

+0

不是没有滚动你自己的窗口铬。 – Nate 2010-05-10 16:02:18

+1

你可以摆脱最小值最大值并关闭 – 2010-05-10 16:06:35

0

这应该从关闭停止窗口: 的FormClosing(对象发件人,System.EventArts E) { 如果(e.CloseReason == CloseReason.UserClosing) e.Cancel = TRUE; }

+1

System.EventArts [原文如此]或EventArgs没有CloseReason成员,您需要FormClosingEventArgs,如我的回答 – 2010-05-10 15:34:42

1

顺便说一句,有没有这个 方法更好的名字?

关闭[FormName]可能是更好的选择。

或者应该是this.Close();

是的,如果你想要的只是关闭窗体。

您应该为FormClosing事件创建一个新的事件处理程序。它采用FormClosingEventArgs而不是EventArgs作为参数。在按钮和菜单项的点击处理程序中,只需执行this.Close()即可。

这将调用该事件,您可以将所有支票放在那里。

3

为按钮/菜单中选择创建一个单独的方法密切:

private void myButton_Click(object sender, EventArgs e) 
{ 
    this.Close(); 
} 

private void myMenuButton_Click(object sender, EventArgs e) 
{ 
    this.Close(); 
} 

private void myForm_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if (m_configControl.Modified) 
    { 
     var result = MessageBox.Show("Name Of Application", "Would you like to save before closing?", MessageBoxButtons.YesNoCancel); 
     if(result == DialogResult.Yes) 
      //Save here 
     else if(result == DialogResult.Cancel) 
      e.Cancel = true; 
    } 
} 

或者,也可以完全通过设置this.ControlBox = false

+0

+1用于创建单独的方法并分解答案。 =) – 2010-05-10 16:04:32

1

FormClosed event禁用关闭按钮(“X”)发生一次的形式关闭了。这绝对不是你想要的。

FormClosing event更可能是你需要的。

FormClosing事件触发任何按钮或菜单链接被点击。任何试图关闭表单的事件都会触发FormClosing事件。

现在,使用FormClosingEventArgs的更合适的方式将是你的FormClosing事件处理方法中的以下内容:

if(m_configControl.Modified) 
    e.Cancel = true; 

所以除非配置控制被修改,表单将关闭。只有在存在更改或未保存的更改时,才想阻止它关闭。

EDIT 2重读你的问题后,请参阅我下面的更改上代码:

if(m_configControl.Modified) 
    if(DialogResult.OK == MessageBox.Show("Do you want to save changes?", "Changes detected") 
     SaveChanges(); 

这则提示未保存的更改用户和保存只有当用户在MessageBox点击OK。请注意,您必须在MessageBox.Show()方法的附加参数中相应地添加按钮。

如果你想完成的是/否/取消后的FormClosing,那么你将不得不走这条路:

if(m_configControl.Modified) { 
    DialogResult dr = MessageBox.Show(...); 
    switch(dr) { 
     case DialogResult.OK: 
      SaveChanges(); 
      break; 
     case DialogResult.No: 
      // Do nothing... 
      break; 
     case DialogResult.Cancel: 
      e.Cancel = true; 
    } 
} 

所以,当用户点击是的,你的应用程序将保存更改。当他点击“否”时,应用程序将不会执行任何操作,并将继续关闭。当用户希望回到应用程序时,关闭将被阻止。

编辑1注意我对This Question的回答,这看起来相当你想要完成的。