2013-08-26 115 views
1

在這個網站上也有類似的問題,但我還沒有找到真正有效的答案,所以我再次發佈它。計算屬性中的通知變更

public MyClass 
{ 

    public person Person1 {get; set;} 

    public person Person2 {get; set;} 

    CalculatedProperty 
    { 
    get 
    { return Person1.Salary + (Person2.Salary/2) ; } 
    } 

} 

public class Person 
{ 
    public double Salary 
    { get; set;} 
} 

我希望能夠在CalculatedProperty每當Person1.Salary和/或Person2.Salary變化更改通知。

我曾嘗試在Person1Person2的setter上添加OnPropertyChanged("CalculatedProperty"),但它不起作用(我理解爲什麼),但無法找到通知更改的方式。請幫助=)

(有沒有用於此的ObjectDataProvider的方法嗎?...一直試圖太...)

+0

你是什麼意思通知? – Renan

回答

5

您需要Person實現INotifyPropertyChanged過,然後註冊兩個屬性,你有。一旦PropertyChangedSalary在其中一方的調用,調用PropertyChangedCalculatedProperty

void PersonPropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    if(e.PropertyName == "Salary") 
     OnPropertyChanged("CalculatedProperty"); 
} 

只記得當人改變註銷。

UPDATE:

正如吉姆說,你的二傳手應該是這個樣子:

private Person _person; 
public Person Person 
{ 
    get { return _person; } 
    set 
    { 
     if (Equals(value, _person)) return; 

     if (_person != null) 
      _person.PropertyChanged -= PersonPropertyChanged; 

     _person = value; 

     if(_person != null) 
      _person.PropertyChanged += PersonPropertyChanged; 

     OnPropertyChanged("Person"); 
    } 
} 
+0

薪水和CalculatedProperty不在同一個班級中。你測試過了嗎? – Paparazzi

+0

讓'MyClass'訂閱'Person'類的OnChange屬性。 –

+0

@布拉姆,我知道,這就是整個問題。你註冊到'Person'的'PropertyChanged''到'MyClass',並聽取更改。當他們中的任何一個上的「薪水」發生變化時,您可以在'CalculatedProperty'上調用'PropertyChanged'。 – CKII

3

給CLII檢查,但是這是一個完整的例子

using System.ComponentModel; 

namespace NotifyBubble 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     // This method is called by the Set accessor of each property. 
     // The CallerMemberName attribute that is applied to the optional propertyName 
     // parameter causes the property name of the caller to be substituted as an argument. 
     private void NotifyPropertyChanged(String propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = this; 
      Person = new Person(); 
      Person.Salary = 100; 
     } 
     void PersonPropertyChanged(object sender, PropertyChangedEventArgs e) 
     { 
      if (e.PropertyName == "Salary") 
       NotifyPropertyChanged("CalculatedProperty"); 
     } 
     public Double CalculatedProperty 
     { 
      get 
      { 
       return Person.Salary/2; 
      } 
     } 
     private Person _person; 
     public Person Person 
     { 
      get { return _person; } 
      set 
      { 
       if (Equals(value, _person)) return; 

       if (_person != null) 
        _person.PropertyChanged -= PersonPropertyChanged; 

       _person = value; 

       if (_person != null) 
        _person.PropertyChanged += PersonPropertyChanged; 
       NotifyPropertyChanged("Person"); 
      } 
     } 
    } 
    public class Person: INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     // This method is called by the Set accessor of each property. 
     // The CallerMemberName attribute that is applied to the optional propertyName 
     // parameter causes the property name of the caller to be substituted as an argument. 
     private void NotifyPropertyChanged(String propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
     private double salary = 0; 
     public double Salary 
     { 
      get { return salary; } 
      set 
      { 
       if (salary == value) return; 
       salary = value; 
       NotifyPropertyChanged("Salary"); 
      } 
     } 
    } 
} 
0

只是爲了記錄,這是我如何實現相同的問題,但在一個集合(使用不同的例子)

public class Fields : ObservableCollection<Field> 
{ 
    protected override event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(String propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    void FieldPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName == "IsSelected") 
     { 
      NotifyPropertyChanged("SelectedItemsCount"); 
     } 
    } 

    protected override void InsertItem(int index, Field item) 
    { 
    if (item != null) 
      item.PropertyChanged -= FieldPropertyChanged; 

     base.InsertItem(index, item); 

     if (item != null) 
      item.PropertyChanged += FieldPropertyChanged; 
    } 

    protected override void ClearItems() 
    { 
     foreach (Field field in this) 
     { 
      field.PropertyChanged -= FieldPropertyChanged; 
     } 
     base.ClearItems(); 
    } 

    protected override void RemoveItem(int index) 
    { 
     if (this[index] != null) 
      this[index].PropertyChanged -= FieldPropertyChanged; 

     base.RemoveItem(index); 
    } 

    private int selectedItemsCount; 

    public int SelectedItemsCount 
    { 
     //This can be more efficient, not have to count everytime 
     get 
     { 
      selectedItemsCount = 0; 

      foreach (Field field in this) 
      { 
       if (field.IsSelected) 
        selectedItemsCount++; 
      } 

      return selectedItemsCount; 
     } 
    } 


}