查看Windows Power Options,turn off the display
中有两个组合框,一个是Battery
,另一个是Plugged in
。
现在要求是Battery
中的值应始终小于Plugged in
中的值。
因此,如果Battery
最初设置为25分钟,然后Plugged in
设置为10分钟,则Battery
的值应自动更改为5分钟。 更改一个值可能会影响另一个。
代码是实现INotifyPropertyChanged
的简单ViewModel。
public class MyViewModel : INotifyPropertyChanged
{
private uint pluggedIn;
public uint PluggedIn
{
get { return pluggedIn;}
set
{
if (pluggedIn != value)
{
pluggedIn = value;
OnPropertyChanged("PluggedIn");
}
}
}
public uint Battery{...} //the same implementation
}
我修改了setter以应用规则。
set
{
if (pluggedIn != value)
{
pluggedIn = value;
OnPropertyChanged("PluggedIn");
if (Battery >= PluggedIn)
{
Battery = FindTheValueLessThanPluggedIn(); //this can potentially modify the value of PluggedIn from the setter of Battery.
}
}
}
问题。
你可以看到调用Bettery的setter也可能会影响PluggedIn的价值,如果我有其他要求,我将不得不写一些难以阅读/维护的代码来实现这个看似简单的任务。
问题
我可以先计算两个属性的最终值,我需要一个可以同时更新两个属性的“原子”操作(不会相互影响),并且在完成“原子”操作后,触发{{ 1}}两个属性更新UI的事件。
第二个想法
在发布后阅读我的问题之后,我想我已经回答了我自己的问题 - 设置支持字段而不是调用setter,但是其他更好的方式?
PropertyChanged
答案 0 :(得分:3)
这有什么问题:
set
{
if (pluggedIn != value)
{
pluggedIn = value;
if (Battery >= PluggedIn)
{
_battery = FindTheValueLessThanPluggedIn();
OnPropertyChanged("Battery");
}
OnPropertyChanged("PluggedIn");
}
请注意,永远不会调用电池的设定器。
对单个属性的两个OnPropertyChanged
调用就是我如何处理与您类似的所有案例,并且它们运行良好。
或者,我也使用过这种技术:
YourViewModel(){
PropertyChanged += PropertyChangedHandler;
}
void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "Battery":
PluggedIn = CalculateNewValueForPluggedIn();
break;
case "PluggedIn":
Battery = CalculateNewValueForBattery();
break;
}
}
答案 1 :(得分:0)
我的建议是将OnChange事件绑定到您在ViewModel中实现的“原子”方法。这些方法应计算两个下拉菜单的最终值,然后设置Properties PluggedIn和Battery。因此,您根本不需要修改属性的setter,理论上甚至不需要延迟触发PropertyChanged事件(让Property setter为您执行此操作)。
通过将所有逻辑外包给它自己的方法并保持setter简单,属性不会相互干扰。但请注意,虽然使用掩码时将满足所有限制,但这可以通过在代码中手动设置属性来覆盖您的限制。