2013-12-08 17 views
0

TextBoxText屬性綁定到該對象實現INotifyPropertyChanged對象屬性,事件PropertyChanged雖然具有相同的價值可能會閃光兩次: 1)當文本當控件離開它時,在TextBox2)內被改變。文本框休假導致的PropertyChanged被解僱兩次

考慮一種形式的這些方法:

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"); 
    } 

和後端類:

private class MyClass : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

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

要重現該問題,鍵入一些在上文本框,檢查控制檯,然後進入下面的文本框並再次檢查控制檯。在離開時,報告財產變更。爲什麼?

+0

因爲它必將 – DonBoitnott

+0

邊界的確定。爲什麼更新源發生兩次? – Alireza

回答

1

默認值Binding.DataSourceUpdateMode property is OnValidation。在此配置中,僅在發生驗證事件時更新數據源。在你的例子中,你使用OnPropertyChanged模式,所以你另外請求更新數據源,只要文本在TextBox內改變。

這是默認行爲,即綁定類以這種方式實現。如果您想了解更多詳細信息,可以查看Binding.Target_PropertyChangedBinding.Target_Validate帶反射器的方法。

從我的角度來看,這行爲是沒有問題的,但你需要改變二傳手的通過以下方式實現:

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

即使我們假定執行綁定類是錯誤的,我認爲在生成PropertyChanged事件之前檢查值是否已更改是一種很好的做法。

0

基於米哈爾的回答,我找到了解決辦法在關閉的TextBoxCausesValidation屬性爲:

textBox.CausesValidation = false;