如何在c#事件中区分更改是由代码还是由用户进行的

本文关键字:代码 用户 事件 中区 | 更新日期: 2023-09-27 18:15:58

我有一个简单的TextBox,开始为空。我有一个简单的事件,_TextChanged,知道用户何时更改了TextBox中的任何内容。但是,如果我自己在代码中对事件进行任何操作,则会触发该事件。如设置textbox.Text = "Test";或类似。

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

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

如何在c#事件中区分更改是由代码还是由用户进行的

我一直在使用这个过程,它似乎工作得很好。如果事件触发而焦点不在文本框中,那么我忽略请求,所以当我设置文本时,焦点在其他地方,但是当用户在文本框中输入时,它有焦点,所以我承认更改。

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

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

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"相同的事情,但将设置标志,让您的事件处理程序知道忽略事件。

反正你也不能。您可以做的是在进行更改之前删除处理程序,并在进行更改后将其添加回来。

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

如果你的方法有相同的作用域,你正在改变文本框的textNazwa_TextChanged的值(例如,两者都在一个形式),你可以设置一个标志代替,或者如果这对你来说还不够,你可以使用责任链来确定是否应该调用textNazwa_TextChanged方法

我建议你使用绑定你的TextBox与演示者有属性,所以如果你需要改变你的值在代码中(例如测试),你不触发事件或更改UI代码。你唯一需要做的就是在演示器上设置一个值。

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,并添加一个Binding到你的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窗体中实现移动视图演示器(MVP)。