INotifyPropertyChanged最佳实践

时间:2011-09-01 01:25:08

标签: inotifypropertychanged

当我有一个实现INotifyPropertyChanged的类时,是否可以将实现公开为公共方法?

例如,如果我在类上有一个名为“Sum”的属性,并且我想在UI中单击按钮来更新总和,那么最好的方法是什么?

下面是一些伪代码来说明我的意思

classinstance.NotifyPropertyChanged("Sum");
...
public Sum { 
   get { return x + y + z; }
}

2 个答案:

答案 0 :(得分:1)

在.Net中,引发事件的方法的首选做法是将方法声明为protected,以便只能由派生类调用(这是因为只有声明事件的类才能引发它。要从派生类中引发事件,需要一个方法来引发事件。

例如......

protected void OnPropertyChanged(string propertyName)
{
    var handler = this.PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

然后,属性设置器中的类(或派生类)调用此方法,以指示属性已更改,如此...

public object MyProperty
{
    get { return _myProperty; }
    set
    {
        _myProperty = value;
        OnPropertyChanged("MyProperty");
    }
}

然后,其他对象可以订阅此事件,并且每次更改MyProperty属性时都会收到通知。

现在,回答您关于OnPropertyChanged方法是否公开的问题。答案是肯定的,但你应该问自己为什么会出现这种情况。

为什么另一个类知道属性何时发生变化才能调用该方法?如果它已经“知道”属性何时发生变化,那么您首先不需要订阅属性更改事件!只有类本身应该“知道”其中一个属性发生了变化。

在您的示例中您正在通知属性“sum”已更改。但事实并非如此。实际上,您的代码甚至不允许在其自己的类之外更改该属性。

我怀疑你可能想要某种方式来通知sum属性需要重新评估,因为依赖属性已被更改。如果是这种情况,则需要在依赖属性更改时引发属性更改事件。

想象一下,前面显示的对'MyProperty'属性的更改也意味着'Sum'已经改变,然后就会像这样处理:

// This property is used by the 'sum' property so if this changes
// clients need to know that 'sum' has also changed.
public object MyProperty
{
    get { return _myProperty; }
    set
    {
        _myProperty = value;
        OnPropertyChanged("MyProperty");
        OnPropertyChanged("Sum");
    }
}

答案 1 :(得分:0)

要实现base更漂亮:

class ledger1(models.Model):
    name            = models.CharField(max_length=32)
    Closing_balance = models.DecimalField(max_digits=10,decimal_places=2,blank=True,null=True)

class journal(models.Model):
    Date       = models.DateField(default=datetime.date.today)
    By         = models.ForeignKey(ledger1,on_delete=models.CASCADE,related_name='Debitledgers')
    To         = models.ForeignKey(ledger1,on_delete=models.CASCADE,related_name='Creditledgers')
    Debit      = models.DecimalField(max_digits=10,decimal_places=2,null=True)
    Credit     = models.DecimalField(max_digits=10,decimal_places=2,null=True)

寻找https://msdn.microsoft.com/en-us/magazine/mt736453.aspx

也值得