如何在只读属性更改时通知用户界面?

7
在WPF中,我有一个只有get{}的属性。该值来自于方法的返回值。通常在属性set{}中使用NotifyPropertyChanged来通知UI并显示更新后的值。但是对于只有get{}的属性,由于必须执行方法来检查新值或不同值的情况,因此无法检测到是否有可用的新值。
有没有一种更新UI的方式,而不必保留包含方法最后一次返回值的本地变量,这样就需要进行比较?
2个回答

12
但是,仅使用get{}时,无法检测是否有新的或不同的值可用,因为您必须执行该方法来进行检查。
问题归结为:是什么在更改属性?更改属性的方法应该调用您的NotifyPropertyChanged并提供属性的名称,这将反过来导致WPF重新获取该值并更新用户界面。
WPF不关心PropertyChanged事件何时被触发,它只会监听并根据需要刷新绑定。

针对评论的编辑:

听起来这可能是对模型类执行某些操作的结果。在这种情况下,通常您知道一个或多个属性可能会更改,但不一定知道哪些属性会发生更改。如果您的模型实现了INotifyPropertyChanged,则可以通过订阅该事件并通过您的NotifyPropertyChanged方法向UI“冒泡”通知。但是,如果没有实现INotifyPropertyChanged,还有另一种选择。

如果您知道一个或多个属性可能会更改,则可以使用string.Empty作为EventArgs中的PropertyName引发一个PropertyChanged事件。这将导致所有绑定的属性都得到WPF的刷新。这很可能只是在代码中添加像这样的内容:

this.Model.DoSomething(); // This will change 1+ properties
this.NotifyPropertyChanged(string.Empty); // Refresh our entire UI

然而我不建议在所有情况下都这样做,因为它会增加开销,但如果你不知道执行操作时哪些属性会发生变化,这通常是最干净的解决方案。


@4thSpace:这个模型实现了INPC吗?如果是的话,你可以订阅它并“传递”属性更改事件。如果没有,那么你当前如何知道值何时发生变化? - Reed Copsey
3
+1,我不知道你可以用空字符串触发 PropertyChanged 以刷新所有订阅者。 - Fredrik Hedblad
@4thSpace:如果您的模型实现了INPC,那么您的UI只需要绑定到Model.MyPropertyName(假设VM添加了一个“Model”属性来返回模型本身)。 - Reed Copsey
我已经在模型中实现了这个。在属性更改的地方(模型方法内部),我在模型中使用了PropertyChanged("MyProperty")。该属性存在于ViewModel中而不是模型中。不确定我是否做对了。因此,MyProperty不在模型中,因为ViewModel.MyProperty在Model.MyMethod上执行get()。...在遵循NotifyPropertyChanged()之后,我发现PropertyChanged为空。有任何想法为什么会这样吗? - 4thSpace
@4thSpace:如果模型中没有该属性,则此方法将无法正常工作。如果您的ViewModel属性调用并从模型返回一个方法,则ViewModel应该调用该方法,然后引发PropertyChanged事件。但这很奇怪 - 除非您实际获取该值,否则它不会被调用...必须有某种方式来更新... - Reed Copsey
显示剩余2条评论

2

是的。当您更改源数据时,需要在属性上触发INotify。以下是一个示例。

private int _myvalue = 3;

  public bool MyProperty
    {
        get { return IsAProperty(); }
    }

public bool IsAProperty()
{
    return _myvalue + 1 == 4;
}
public void SetValue(int value)
{
    _myvalue = value;
    NotifyPropertyChanged(MyProperty);
}

NotifityPropertyChanged 需要 string 参数。很奇怪这个答案被投票赞同,而它是错误和混乱的(从 setter 调用 IsAProperty() 方法的目的是什么?)。 - Sinatr
如果您使用反射设置它,可以传递属性本身。请注意,此答案已经接近4年了。现在有一些更新的框架可以让您以更清晰的方式完成此操作。如果您认为答案不正确,而不是在评论中抱怨,请编辑答案以使整个社区受益。 - tsells

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接