为什么.NET在接收到INotifyPropertyChanged.PropertyChanged事件时会读取未受影响的属性值?

时间:2009-11-13 02:03:12

标签: .net winforms data-binding inotifypropertychanged propertychanged

我是数据绑定的新手,今天遇到了一些我无法理解的奇怪现象:

我有一个带有两个标签(labelA和labelB)和两个按钮(buttonA和buttonB)的表单。

表单承载一个具有两个属性(CountA和CountB)的对象(称为“formState”)。 labelA.Text与formState.CountA数据绑定, labelB.Text与formState.CountB数据绑定。

当按下buttonA时,它使formState以“CountA”作为属性名称引发PropertyChange事件。 当按下buttonB时,它会将“StateB”作为属性名称引发formState.PropertyChange。

我希望只有buttonA在按下buttonA时才会更新,并且只有buttonB在按下buttonB时才会更新。但是,当我按任何按钮时,两个标签都会更新。我可以看到这一点,因为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 个答案:

答案 0 :(得分:3)

它可能是可观察对象的天真消费者。 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 :(得分:1)

您的班级责任是提供变更通知 - 消费者有责任决定如何处理。如果它选择检查任何属性更改的每个属性,它可以做到这一点。