通知计算财产的变化

时间:2013-08-26 13:38:43

标签: c# wpf notify

在这个网站上有类似的问题,但我没有找到真正有效的答案,所以我再次发布。

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中的更改。

我尝试在OnPropertyChanged("CalculatedProperty")Person1的设置者上添加Person2,但它不起作用(我理解为什么),但无法找到通知更改的方法。请帮忙=)

(有没有办法为此使用ObjectDataProvider?...一直在尝试......)

3 个答案:

答案 0 :(得分:6)

您还需要Person来实施INotifyPropertyChanged,然后注册到您拥有的两个属性。在其中任何一个上使用PropertyChanged调用Salary后,在PropertyChanged上调用CalculatedProperty

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

请记住在人员被更换时取消注册。

<强>更新

正如吉姆所说,你的二传手应该是这样的:

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

答案 1 :(得分: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");
            }
        }
    }
}

答案 2 :(得分: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;
        }
    }


}