简体   繁体   English

如何停止文本框离开事件触发窗体关闭

[英]How to stop textbox leave event firing on form close

using c# winforms vs2008 使用c#winforms vs2008

I've got a textbox on a form with a method being called from the textBox1_Leave event. 我在表单上有一个文本框,其中一个方法是从textBox1_Leave事件中调用的。 The method takes the contents of the textbox in question and populates other textboxes based on the contents. 该方法获取有问题的文本框的内容,并根据内容填充其他文本框。 My problem is that is the user has focus on the text box then clicks the button to close the form (calling this.close) then the form does not close because the textbox leave event gets fired. 我的问题是,用户是否专注于文本框,然后单击按钮关闭表单(调用this.close),然后表单不会关闭,因为文本框离开事件被触发。 If the textbox does not have focus on form close then the form closes fine. 如果文本框没有关注表单关闭,则表单关闭正常。

If however a user closes the form by clicking the little X close icon in the top corner the it closes fine all the time with out the textbox leave event being fired. 但是,如果用户通过单击顶角的小X关闭图标来关闭表单,则它会一直关闭,而不会触发文本框离开事件。

How can I duplicate the X close functionality so that I can always close the form without the textbox leave event being fired? 如何复制X关闭功能,以便我可以随时关闭表单而不会触发文本框离开事件?

The simplest solution is going to be to check which control is actually focused before doing your post-processing - but you can't do it in the Leave handler, because the focus will still be on the text box at that point. 最简单的解决方案是在进行后处理之前检查实际聚焦的控件 - 但是你不能在Leave处理程序中执行它,因为焦点仍然在那个点的文本框中。

Instead, you need to move your logic to the LostFocus event, which is not in the designer. 相反,您需要将逻辑移动到LostFocus事件,而不是设计器中的事件。 You'll have to wire it up at runtime: 你必须在运行时连接它:

public class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        textBox1.LostFocus += new EventHandler(textBox1_LostFocus);
    }

    private void textBox1_LostFocus(object sender, EventArgs e)
    {
        if (closeButton.Focused)
            return;
        // Update the other text boxes here
    }
}

The LostFocus event happens to fire after the new control receives focus. LostFocus事件在新控件获得焦点触发。

Clarification - you might find that it works by putting this logic in the Leave event - if the focus is changed by the mouse . 澄清 - 您可能会发现它的工作原理是将此逻辑放在Leave事件中 - 如果鼠标更改了焦点 If the keyboard is used instead, you'll get the wrong behaviour. 如果使用键盘,你将得到错误的行为。 LostFocus is reliable in both cases - the focused control will always be the "new" control. LostFocus两种情况下都是可靠的 - 聚焦控制始终是“新”控制。 This is documented on MSDN: Order of Events in Windows Forms . 这在MSDN上记录: Windows窗体中的事件顺序

Incidentally, the reason why you're not having this problem with the "red X" is that the X is not actually a control that can receive focus, it's part of the window. 顺便说一句,你没有遇到“红色X”这个问题的原因是X实际上不是一个可以获得焦点的控件,它是窗口的一部分。 When the user clicks that, it's not causing the text box to lose focus, and therefore isn't causing the Leave event to fire. 当用户单击它时,它不会导致文本框失去焦点,因此不会导致Leave事件触发。

Another approach: Use the textbox's validating event instead of it's leave event, then change the button's CausesValidation property to false. 另一种方法:使用文本框的验证事件而不是它的离开事件,然后将按钮的CausesValidation属性更改为false。 You will also have to set the textbox to not cause validation in the button's click event so the validating event will not fire when the form is closing (thanks to @Powerlord for pointing this out). 您还必须将文本框设置为不在按钮的单击事件中进行验证,以便在表单关闭时不会触发验证事件(感谢@Powerlord指出这一点)。

private void button1_Click(object sender, EventArgs e)
{
    this.textBox1.CausesValidation = false;
    this.Close();
}

You could also handle the FormClosing event and make sure the e.Cancel argument does not get set to true by the validating events on the other controls on the form. 您还可以处理FormClosing事件,并确保e.Cancel参数不会通过窗体上其他控件上的验证事件设置为true。 I think they will be fired off before the FormClosing event. 我认为它们将在FormClosing事件之前被解雇。

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {   
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = false;
                return;
            }
        }

you can check to see which control has just got focus. 你可以查看哪个控件刚关注。

private void textBox1_Leave(object sender, EventArgs e)
{
    if (btnClose.Focused)
        return;
    // go from here
}

Just check if the form owning the textbox is disposing? 只检查拥有文本框的表单是否正在处理? If it's getting closed, it's disposing. 如果它关闭了,它就会被处理掉。 If it's disposing you could simply end the pesky 'leave' event without doing anything. 如果它处理你可以简单地结束讨厌的'离开'事件而不做任何事情。 I didn't check it and forgive me, I'm choked on a project of my own so and I was searching myself, so I don't think I'll have time for that. 我没有检查它并原谅我,我对自己的项目感到窒息,所以我正在寻找自己,所以我认为我没有时间。

private void GuiltyTextBox_Leave(object sender, EventArgs e) {
  Form formOwningTheTextBox=(Form)((Control)sender).TopLevelControl;
  if (formOwningTheTextBox.Disposing || formOwningTheTextBox.IsDisposed) return;
  .......
}

I just believe this is going to work with minimum effort and wanted to send a quick answer before I resume searching my own answer. 我只相信这会以最小的努力工作,并希望在我继续搜索我自己的答案之前发送快速答案。

Write Following line of code in text box leave event on top 在文本框中写下面的代码行将事件放在最上面

if me.closing then
return
end if

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM