Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在窗体关闭时停止文本框离开事件触发_C#_Winforms_Textbox_Events - Fatal编程技术网

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

C# 如何在窗体关闭时停止文本框离开事件触发,c#,winforms,textbox,events,C#,Winforms,Textbox,Events,使用c#winforms vs2008 我在表单上有一个textbox,其中有一个从textBox1\u Leave事件调用的方法。该方法获取相关文本框的内容,并根据内容填充其他文本框。 我的问题是,用户将焦点放在文本框上,然后单击按钮关闭表单(调用this.close),然后表单不会关闭,因为文本框离开事件被触发。 如果文本框的焦点不在表单关闭上,则表单将正常关闭 但是,如果用户通过单击上角的小X close图标关闭表单,则该表单将始终正常关闭,不会触发out textbox leave事件

使用c#winforms vs2008

我在表单上有一个textbox,其中有一个从textBox1\u Leave事件调用的方法。该方法获取相关文本框的内容,并根据内容填充其他文本框。 我的问题是,用户将焦点放在文本框上,然后单击按钮关闭表单(调用this.close),然后表单不会关闭,因为文本框离开事件被触发。 如果文本框的焦点不在表单关闭上,则表单将正常关闭

但是,如果用户通过单击上角的小X close图标关闭表单,则该表单将始终正常关闭,不会触发out textbox leave事件


如何复制X close功能,以便在不触发textbox leave事件的情况下始终关闭表单?

您可以检查哪个控件刚刚获得焦点

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

最简单的解决方案是在进行后期处理之前检查哪个控件实际处于焦点位置,但不能在
Leave
处理程序中进行,因为此时焦点仍然在文本框上

相反,您需要将逻辑移到设计器中不存在的
LostFocus
事件。您必须在运行时将其连接起来:

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
    }
}
新控件收到焦点后,
LostFocus
事件发生

澄清-如果鼠标改变焦点,您可能会发现将此逻辑放入
离开
事件中。如果改用键盘,你会得到错误的行为
LostFocus
在这两种情况下都是可靠的-聚焦控件始终是“新”控件。这在MSDN上有记录:

顺便说一句,“红色X”没有这个问题的原因是X实际上不是一个可以接收焦点的控件,它是窗口的一部分。当用户单击该按钮时,它不会导致文本框失去焦点,因此也不会导致触发
Leave
事件。

另一种方法: 使用文本框的validating事件而不是leave事件,然后将按钮的CausesValidation属性更改为false。您还必须将文本框设置为不会在按钮的单击事件中导致验证,以便在表单关闭时不会触发验证事件(感谢@Powerlord指出这一点)


您还可以处理FormClosing事件,并确保表单上其他控件上的验证事件不会将e.Cancel参数设置为true。我想他们会在闭幕式之前被解雇

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

只需检查拥有文本框的表单是否正在处理?如果它关闭了,它就被丢弃了。如果是这样的话,你可以不做任何事情就结束这个讨厌的“离开”事件。我没有检查它,原谅我,我被自己的一个项目噎住了,所以我在搜索自己,所以我想我没有时间做这个

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

我只是相信这将以最小的努力工作,并希望在我继续搜索我自己的答案之前发送一个快速的答案。

在文本框中写下以下代码,将事件保留在顶部

if me.closing then
return
end if

您很接近-但是在
Leave
事件中焦点尚未改变。我不同意关于
Leave
给出错误行为的评论,请参见-(顺便说一句,在接收控件调用
Enter
之前,焦点参数已更改,这在事件顺序中排在第一位),具体取决于所需的功能,这种方法也可能有问题。如果“关闭”按钮位于文本框后的选项卡顺序中的下一个按钮,并且用户按tab键离开文本框,这将阻止您想要的更新发生,即使它们应该发生。我会尝试一下,看看它是什么样子的谢谢大家的支持input@Robert罗斯尼:这似乎是我们想要的行为,不是问题;显然,当文本框失去焦点时,会触发一些逻辑,他不希望在用户想要关闭表单时触发这些逻辑,这将包括在下一行时切换到关闭按钮。“完整”的解决方案会在关闭按钮失去焦点时触发相同的逻辑,除非焦点被更改回原始文本框。@Courtney:正如我所解释的,只有在鼠标动作时,焦点控件才会被更改;您的程序也必须适用于键盘操作。我经常对我使用的许多程序感到沮丧,这些程序没有正确地测试键盘导航,并且做了一些事情,比如搞乱了标签顺序。
if me.closing then
return
end if