3

我有一种情况,我有几个变量的值相互依赖,如下所示:

A 是 B 和 C 的函数 B 是 A 和 C 的函数 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 呈现错误信息。事情是 this[columnName] 索引器在设置器的末尾被调用,我需要在计算之前验证值,这样如果值输入无效,计算不会发生。我正在认真考虑放弃 IDataErrorInfo 并在计算发生之前简单地调用我的验证方法。有什么方法可以显式调用它或在价值归因之后立即调用它?

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

4

2 回答 2

2

可以在 Setter 中调用您的验证和计算,只要它不阻塞线程并进入繁重的 CPU 密集型计算。如果你有简单的 5 到 10 个基于数学的语句,而不涉及复杂的循环,那没关系。

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

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

IEditableObject 将最适合性能,但它可能不会显示新值,直到它被取消或结束,但是立即显示唯一的方法就是你正在做的方式。

如果 cpu 使用量很大,您可以调用另一个线程来进行计算和设置变量,最后您可以触发 PropertyChanged,但是从技术上讲,您只是在做同样的事情,同时在 setter 中异步设置值。

于 2009-12-28T07:51:36.427 回答
1

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

于 2009-12-28T22:01:58.507 回答