TextBox离开导致PropertyChanged被触发两次

时间:2013-12-08 19:08:52

标签: c# winforms binding

Text的{​​{1}}属性绑定到该对象实现TextBox的对象属性时,事件INotifyPropertyChanged可能会触发两次,同时具有相同的值:   1)当控件离开时,PropertyChanged 2)内的文字发生了变化。

考虑以下形式的方法:

TextBox

和后端课程:

    private void Form1_Load(object sender, EventArgs e)
    {
        TextBox textBox = new TextBox();
        TextBox secondTextBox = new TextBox();
        secondTextBox.Location = new Point(0, 100);

        this.Controls.Add(textBox);
        this.Controls.Add(secondTextBox);

        MyClass instance = new MyClass();
        instance.PropertyChanged += instance_PropertyChanged;

        textBox.DataBindings.Add("Text", instance, "Id", true, DataSourceUpdateMode.OnPropertyChanged);
    }

    private void instance_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine(e.PropertyName + " changed");
    }

要重现此问题,请在上方文本框中键入内容,检查控制台,然后输入下方文本框并再次检查控制台。离开后,报告财产变更。为什么呢?

2 个答案:

答案 0 :(得分:1)

Binding.DataSourceUpdateMode 属性的默认值为 OnValidation 。在此配置中,仅在发生验证事件时才更新数据源。在您的示例中,您使用 OnPropertyChanged 模式,因此只要在TextBox中更改文本,另外就会请求更新数据源。

这是默认行为,即 Binding 类以这种方式实现。如果需要更多详细信息,可以使用反射器检查 Binding.Target_PropertyChanged Binding.Target_Validate 方法。

从我的角度来看,这种行为不是问题,但您需要以下列方式更改setter的实现:

set
{
    if(_id != value)
    {
        _id = value;
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Id"));
    }
}

即使我们假设 Binding 类的实现是错误的,我认为在生成 PropertyChanged 事件之前检查值是否已更改是一个好习惯。

答案 1 :(得分:0)

根据Michal的回答,我找到了关闭CausesValidation TextBox属性的解决方案:

textBox.CausesValidation = false;