2009-12-28 35 views
3

我有一个情况我有几个变量谁的值是互相依赖的是这样的:的PropertyChanged影响几个属性

A是B和C的功能 B是A的功能和C Ç是A和B的函数

任何值都可以在UI上更改。我正在做的计算和改变通知这样的:

private string _valA; 
private string _valB; 
private string _valC; 

public string ValA 
{ 
    get { return _valA; } 
    set 
    { 
     if (_valA != value) 
     { 
      _valA = value; 
      RecalculateValues("ValA");  //Here ValB and ValC are calculated 
      OnPropertyChanged("ValA"); 
     } 
    } 
} 

public string ValB 
{ 
    get { return _valB; } 
    set 
    { 
     if (_valB != value) 
     { 
      _valB = value; 
      RecalculateValues("ValB");  //Here ValA and ValC are calculated 
      OnPropertyChanged("ValB"); 
     } 
    } 
} 

(...) 

private void RecalculateValues(string PropName) 
{ 
    if (PropName == "ValA") 
    { 
     _valB = TotalValue * _valA; 
     OnPropertyChanged("ValB"); 

     _valC = something * _valA 
     OnPropertyChanged("ValC"); 
    } 
    else 
    (...) 

} 

我打电话上改变的变量的设定器的计算方法,计算_valB,_valC(例如)中的值,然后调用的PropertyChanged为这些。 我这样做是因为变量之间的依赖关系,就像我可以控制哪个变量用正确的值计算一样。我也想过为其他变量触发PropertyChanged,并对变量的getter进行计算,但是我必须知道哪些属性在之前更改过,并使用该值......不确定它是否是最好/最简单的解决方案。

这是一个很好的方法吗?我不喜欢在setter块上执行此操作的想法,但是当时我看不到任何更好的方法来做到这一点。您是否看到任何其他(更好或更清洁的解决方案)?

我的另一个问题是使用IdataErrorInfo验证/向UI呈现错误信息。事情是这个[columnName]索引器在setter结束时被调用,我需要在计算之前验证值,所以如果输入的值无效,计算就不会发生。我正在认真考虑放弃IDataErrorInfo,并在发生计算之前简单地调用我的验证方法。有没有什么方法可以明确地调用它或者在值归属之后?

注意:ValidationRules不是一个选项,因为我需要从我的ViewModel调用另一个对象上的验证逻辑。

+0

你有'_valA'等输入为字符串,但你在字符串上执行“乘法”,如'_valB = TotalValue * _valA'。请解释。 – jason 2009-12-28 01:17:05

回答

2

它可以在Setter中调用您的验证和计算,只要它不会阻塞线程并进入繁重的cpu密集计算。如果你有简单的5-10数学基础陈述,而不涉及复杂的循环,那就好了。

对于数据绑定和WPF,这是唯一的方法,但是还有一个叫做IEditableObject的实现,它有BeginEdit,CancelEdit和EndEdit,您可以在其中对EndEdit函数进行计算和验证。

在BeginEdit中,你可以将所有的值保存在临时存储器中,在CancelEdit中你可以从temp中取回所有的值,并为所有被修改的值触发PropertyChaged事件,在EndEdit中,你可以最终更新所有变量并触发PropertyChanged所有这些更新。

IEditableObject对于性能方面是最好的,但它可能不会显示新的值直到它被取消或结束,但要立即显示唯一的方法就是执行它。

如果CPU使用率过高,您可以调用另一个线程来进行计算和设置变量,最后您可以触发PropertyChanged,但是技术性的,您只是在setter中设置值而非异步执行相同的操作。

1

由于您可以从类中的任何位置调用NotifyPropertyChanged,因此简化此操作的一种方法是让您的Calculate方法触发所有三个变量的NotifyPropertyChanged。当我使用多重依赖关系进行复杂计算时,我使用这个技巧。有时你仍然想在Setter中触发事件:在这种情况下,当我从计算内更新属性时,我使用标志字段来禁用事件,以便事件不会被触发两次。