PropertyChanged影响了几个属性

时间:2009-12-28 01:07:52

标签: c# wpf inotifypropertychanged idataerrorinfo

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

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
    (...)

}

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

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

我遇到的另一个问题是使用IdataErrorInfo验证/向UI显示错误信息。事情是这个[columnName]索引器在setter的末尾被调用,我需要在计算之前验证这些值,这样才能如果输入的值无效,则计算不会发生。我正在认真考虑放弃IDataErrorInfo并在计算发生之前简单地调用我的验证方法。有没有办法明确地调用它或者在值归属之后?

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

2 个答案:

答案 0 :(得分:2)

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

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

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

IEditableObject最适合性能,但在取消或结束之前可能不会显示新值,但是要立即显示,唯一的方法就是你这样做。

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

答案 1 :(得分:1)

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

相关问题