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

CalculatedPropertyいつでも変更Person1.Salaryや変更を通知できるようにしたいPerson2.Salary

andOnPropertyChanged("CalculatedProperty")のセッターを追加しようとしましたが、機能しません (理由は理解しています) が、変更を通知する方法が見つかりません。助けてください=)Person1Person2

(これに an を使用する方法はありObjectDataProviderますか?...それも試しています...)

4

3 に答える 3

6

Personあなたも実装する必要がありINotifyPropertyChanged、それからあなたが持っている2つのプロパティに登録してください。いずれかでPropertyChanged呼び出されたら、 onで呼び出しますSalaryPropertyChangedCalculatedProperty

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 に答える