Почему .NET читает значения незатронутых свойств при получении события INotifyPropertyChanged.PropertyChanged? - PullRequest
1 голос
/ 13 ноября 2009

Я новичок в связывании данных и столкнулся со следующей странностью, которую не понимаю:

У меня есть форма с двумя метками (labelA и labelB) и двумя кнопками (buttonA и buttonB).

Форма содержит объект (называемый "formState") с двумя свойствами (CountA и CountB). labelA.Text привязан к данным для formState.CountA, labelB.Text привязан к данным для formState.CountB.

Когда кнопка A нажата, она заставляет formState вызвать событие PropertyChange с именем CountA в качестве имени свойства. Когда кнопка B нажата, она вызывает formState.PropertyChange с "CountB" в качестве имени свойства.

Я ожидаю, что только ярлык A обновляется при нажатии кнопки A, и только ярлык B обновляется при нажатии кнопки B. Тем не менее, обе метки обновляются, когда я нажимаю любую кнопку. Я вижу это, потому что свойства CountA и CountB увеличивают и возвращают счетчик каждый раз, когда их значения читаются. Код ниже.

У кого-нибудь есть объяснение этому поведению?

public partial class Form1 : Form
{
    private FormState formState = new FormState();

    public Form1()
    {
        InitializeComponent();

        labelA.DataBindings.Add(
            new Binding("Text", formState, "CountA"));

        labelB.DataBindings.Add(
            new Binding("Text", formState, "CountB"));
    }

    private void buttonA_Click(object sender, EventArgs e)
    {
        formState.raisePropertyChangedEvent("CountA");
        // both labelA and labelB get updated - why not just labelA?
    }

    private void buttonB_Click(object sender, EventArgs e)
    {
        formState.raisePropertyChangedEvent("CountB");
        // both labelA and labelB get updated - why not just labelB?
    }

    public class FormState : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private int countA = 0;
        private int countB = 0;

        public int CountA
        {
            get { return ++countA; }
        }

        public int CountB
        {
            get { return ++countB; }
        }

        public void raisePropertyChangedEvent(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

Ответы [ 2 ]

3 голосов
/ 13 ноября 2009

Это может быть наивный потребитель наблюдаемых объектов. Наивные потребители INotifyPropertyChangedObjects могут игнорировать имя свойства и просто заново оценить все это. Можно представить, что класс выглядит так:

class NaiveConsumer
{
   void Foo(INotifyPropertyChanged observable)
   {
       observable.PropertyChanged += PropertyChangedHandler;
   }

   void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
   {
      // Evaluate all properties, even though only 1 prop changed.
      this.NameTextBox.Text = observable.Name;
      this.AgeTextBox.Text = observable.Age;
   }
}
1 голос
/ 13 ноября 2009

В обязанности вашего класса входит предоставление уведомления об изменениях, а ответственность потребителя заключается в том, чтобы решить, что с ним делать. Если он решит проверить каждое свойство в любом измененном свойстве, он может это сделать.

...