12

这更像是一个架构/设计问题。

过去,我遇到过一些用 WPF/Windows 窗体等编写的项目,这些项目具有带有很多字段的复杂屏幕,并且这些字段相互连接(它们的值相互依赖,涉及一些逻辑)。

这些项目是我在实施后承担的,我发现了很多事件/数据绑定地狱——我的意思是因为所有这些字段都依赖于其他字段,它们已经实现了 INotifyPropertyChanged 并且其他字段正在被修改为结果。这会导致相同的字段在屏幕加载时更新 5-6 次,并且填充字段的顺序会导致可怕的错误。(例如,Date设置在Job Type之前,而不是Job Type之后,所以我最终得到了不同的Job Fee。)

更糟糕的是,一些 hack 是在 UI 事件上实现的(例如,DropDown 更改为更新字段 X),而另一些则在 UI 绑定到的域模型中。

基本上,这是一个巨大的混乱,我只想知道如果我从头开始,实现这样的事情的最佳方法是什么。还是首先避免使用如此复杂的屏幕是个好主意?

4

2 回答 2

2

我会尽量将业务逻辑排除在属性设置器之外。

首先,如果一个计算需要多个属性,我会编写一个进行计算的方法,并在适当的时候调用该方法。例如,如果属性值的所有不同组合都有意义,则可以只在每个属性的设置器中调用该方法,以确保在任何一个属性更改时运行相同的代码。如果您只能评估属性值的特殊组合,您可以实现一个命令并让用户决定何时计算结果更改,或者您可以通过验证提供反馈,并且仅在组合有效时评估属性更改。如果有几个相互依赖的属性,我经常使用“ChangeInitiator”变量来指示哪些属性发生了变化,以便在计算方法中明确哪个属性负责更改以及哪些其他属性应该因此而更改。基本上,这与在每个属性设置器中进行计算的一部分相同,但我发现如果关系的不同部分都在一个方法中,它有助于我保持对事物的概览。

在我曾经写过的一个程序中,我会定期在后台线程上运行一些计算,因此每当需要进行新计算的数据发生变化时,我都会设置一个标志,并每隔一秒左右根据计时器进行所有更新...这也可以帮助您更直接地理解逻辑,并且避免为一组相关更改运行多次计算。

关于更改通知,我真的会尝试仅将其用于 UI 数据绑定。

于 2013-05-03T06:38:02.283 回答
0

我们有相当复杂的 UI(包括几个不同类型的相关字段,例如 DataGrid 中的行),MVVM 模式对我们来说效果很好。所有来自模型并暴露给视图的具有复杂逻辑相关的属性都被 ViewModel 中的等效属性“包装”,该属性没有支持字段,而是直接指向模型:

public class SomeComplexViewModel
{

    public SomeModel Model {get;set;}

    public string SomeCrazyProperty
    {
       get
       {
          return Model.SomeCrazyProperty;
       }
       {
          Model.SomeCrazyProperty = value;
          //... Some crazy logic here, potentially modifying some other properties as well.
       }
    }
}

<TextBox Text="{Binding SomeCrazyProperty}"/>

这消除了“初始值”问题,因为 Binding 读取的初始值实际上是来自 Model 的真实值,因此放置在其中的逻辑Setter仅在需要时执行。

然后,对于虚拟属性(背后没有逻辑),我们直接从视图绑定到模型:

<TextBox Text="{Binding Model.SomeRegularProperty}"/>

这减少了 ViewModel 中的膨胀。

关于后面代码中的事件,我完全避免这样做。我的文件背后的代码几乎总是一个InitializeComponent(),没有别的。

只有 View-Specific 逻辑放在后面的代码中(例如动画等),当它不能直接在 XAML 中完成时,或者在代码中更容易完成时(大多数情况下并非如此)。

编辑:

值得一提的是,与基于 XAML 的绑定功能相比,winforms 绑定功能是个笑话。这可能是您在这些项目中看到那些可怕的混乱的原因吗?

于 2013-05-03T01:27:48.830 回答