3

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

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

我希望能够随时通知更改CalculatedPropertyPerson1.Salary/或Person2.Salary更改。

我尝试添加OnPropertyChanged("CalculatedProperty")setter,Person1Person2它不起作用(我理解为什么),但找不到通知更改的方法。请帮忙=)

(有没有办法使用ObjectDataProvider这个?......也一直在尝试......)

4

3 回答 3

6

您也需要Person实现INotifyPropertyChanged,然后注册到您拥有的两个属性。一旦在其中任何一个上PropertyChanged调用Salary,调用PropertyChangedCalculatedProperty

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");
    }
}
于 2013-08-26T13:45:40.783 回答
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");
            }
        }
    }
}
于 2013-08-26T15:10:23.423 回答
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;
        }
    }


}
于 2014-07-09T10:40:37.167 回答