如果从代码或用户进行更改,如何区分C#事件?

Mad*_*Boy 28 c# winforms

我有一个简单TextBox的开头是空的.我有一个简单的事件,_TextChanged,以了解用户何时更改了该内容TextBox.但是,如果我在代码中自己做任何事情,事件就会触发.喜欢设置textbox.Text = "Test";或类似.

    private void textNazwa_TextChanged(object sender, EventArgs e) {
        changesToClient = true;
    }
Run Code Online (Sandbox Code Playgroud)

如何使事件仅激发用户交互而不是代码更改?

rwg*_*rwg 35

我一直在使用这个过程,它似乎运作良好.如果事件触发并且焦点不在文本框中,则忽略该请求,因此当我设置文本时焦点位于其他位置,但是当用户在文本框中键入时,它具有焦点,因此我确认更改.

private void textNazwa_TextCanged(object sender, EventArgs e)
{
    if ( !textNazwa.Focused) 
        return; 
}
Run Code Online (Sandbox Code Playgroud)

  • 哇,这非常巧妙.当然可能有一些罕见的情况,你有一个定时器触发的绑定更新,用户恰好同时使用该控件,但这将是一个糟糕的设计开始.对于我的用例,这个解决方案是最好的. (2认同)

Ada*_*son 20

事件本身不区分通过用户输入输入的文本和通过代码更改的文本.您必须自己设置一个标志,告诉您的代码忽略该事件.例如,

private bool ignoreTextChanged;

private void textNazwa_TextCanged(object sender, EventArgs e)
{
    if (ignoreTextChanged) return;
}
Run Code Online (Sandbox Code Playgroud)

然后使用它来设置文本而不是只调用Text = "...";:

private void SetTextboxText(string text)
{
    ignoreTextChanged = true;

    textNazwa.Text = text;

    ignoreTextChanged = false;
}
Run Code Online (Sandbox Code Playgroud)

从你对另一个答案的评论判断,听起来你有很多文本框.在这种情况下,您可以通过以下方式修改函数:

private void SetTextBoxText(TextBox box, string text)
{
    ignoreTextChanged = true;

    box.Text = text;

    ignoreTextChanged = false;
}
Run Code Online (Sandbox Code Playgroud)

然后像这样称呼它:

SetTextBoxText(textNazwa, "foo");
Run Code Online (Sandbox Code Playgroud)

这将完成与刚刚完成相同的操作textNazwa.Text = "foo",但会设置标志,让您的事件处理程序知道忽略该事件.

  • 那实际上更好的想法是禁用/启用事件. (2认同)

Con*_*rix 5

好吧,你无论如何都不能没有.您可以做的是在进行更改之前删除处理程序,并在进行更改后将其添加回来.

例如

  textNazwa.TextChanged -= textNazwa_TextChanged;
  textbox.Text = "Test";
  textNazwa.TextChanged += textNazwa_TextChanged;
Run Code Online (Sandbox Code Playgroud)

如果您的方法与更改文本框的值的范围相同textNazwa_TextChanged(例如,两者都在一个表单中),您可以设置一个标志,或者如果这对您来说不够,那么您可以使用Chain of Responsiblity确定是否textNazwa_TextChanged应该调用该方法