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

时间:2011-11-27 19:45:47

标签: c# winforms

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

    private void textNazwa_TextChanged(object sender, EventArgs e) {
        changesToClient = true;
    }

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

5 个答案:

答案 0 :(得分:30)

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

private void textNazwa_TextCanged(object sender, EventArgs e)
{
    if ( !textNazwa.Focused) 
        return; 
}

答案 1 :(得分:19)

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

private bool ignoreTextChanged;

private void textNazwa_TextCanged(object sender, EventArgs e)
{
    if (ignoreTextChanged) return;
}

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

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

    textNazwa.Text = text;

    ignoreTextChanged = false;
}

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

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

    box.Text = text;

    ignoreTextChanged = false;
}

然后这样称呼:

SetTextBoxText(textNazwa, "foo");

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

答案 2 :(得分:6)

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

e.g。

  textNazwa.TextChanged -= textNazwa_TextChanged;
  textbox.Text = "Test";
  textNazwa.TextChanged += textNazwa_TextChanged;

如果您的方法与您将文本框的值更改为textNazwa_TextChanged的范围相同(例如,两者都在表单中),您可以设置一个标记,或者如果它不足以显示您,您可以使用Chain of Responsiblity来确定是否应该调用textNazwa_TextChanged方法

答案 3 :(得分:2)

我建议您使用具有属性的演示者为TextBox使用Bindings,因此如果您需要更改代码中的值(例如测试),则不要触发事件或更改为UI代码。您唯一需要做的就是在Presenter上设置一个值。

public class Presenter : INotifyPropertyChanged
{
    public string MyTextValue { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
    /// Create a method here that raises the event that you call from your setters..
}

然后在Windows窗体代码中,您需要将一个bindingSource设置为Presenter,并为您添加一个绑定textBoxes:

修改

private BindingSource myPresenterSource ;
this.myPresenterSource = new System.Windows.Forms.BindingSource(this.components);
// Some time later in the

((System.ComponentModel.ISupportInitialize)(this.myPresenterSource )).BeginInit();
// you set the DataSource of your BindingSource
// m_SettingsBindingSource
//
this.myPresenterSource .DataSource = typeof(Presenter );

// and when you create your TextBox you do this :
this.YourTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text",
   this.myPresenterSource, "MyTextValue", true,
   System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));

然后在InitializeComponent中设置源代码如下:

myPresenterSource.DataSource = new Presenter();

通过查找如何在Windows窗体中实现Movel-View-Presenter(MVP)来检查更多资源。

答案 4 :(得分:0)

对我来说,我会以这种方式实现它

bool wasUserTyping = false;
private void textNazwa_KeyUp(object sender, KeyEventArgs e){
     wasUserTyping = true;
}

private void textNazwa_TextChanged(object sender, TextChangedEventArgs e){
    if(wasUserTyping){
          //Yaaay!! User did type
    }
}