我需要一个跟踪更改的视图模型,以便用户可以看到视觉上发生的变化以响应编辑和回滚部分。现在,我“打开”更改跟踪作为视图模型的构造函数的最后一步(必要,因为有时视图模型是从模板构造的,或者在构造完成之前具有触发PropertyChanged
的默认逻辑,错误地甚至在用户做了任何事情之前就认为它已经改变了。
这大部分都有效,
是否有更好的地方可以启用更改跟踪?
答案 0 :(得分:0)
在理想的MVVM实现中,既不是更好也不是替代的地方,因为您不太可能知道视图何时或如何与视图模型通信。实际上,视图模型不应该对视图有任何了解。视图可能是Silverlight UI或控制台应用程序,或测试模型,或其他任何内容。根据一般的想法,构造函数似乎是唯一应该禁用“更改跟踪”的地方。
如果您严格遵循MVVM,则应将视图模型视为主要对象,将视图视为次要视图。我的意思是视图不应该引入任何与特定视图实现无关的逻辑。它仅显示当前视图模型状态,并将用户的操作传递给视图模型。如果这是真的,那么除了构造函数之外,你不需要在任何地方关闭变更跟踪。
当然,在现实世界中,这可能很难遵循。如果找不到其他解决方案,则可以向视图模型引入其他属性,例如: IsViewInitialized
,会启用“更改跟踪”,并使视图根据需要设置属性。
但你最好尽可能地避免这种情况。这种方法增加了Views和ViewModels之间的耦合,这与MVVM模式的主要思想之一相对。
如果你个人问我,我的视图模型很少有初始化步骤的替代逻辑,如果他们这样做,它只在构造函数中。我通常不会“关闭更改跟踪”,而是直接设置一些字段以绕过常规更改跟踪代码,这些代码大多数情况下都位于属性设置器中。但有时甚至在构造函数中触发某些属性的逻辑也更方便。
答案 1 :(得分:0)
通常,处理变更跟踪没有“正确”或“错误”的地方。
但是如果您更喜欢在VM中执行此操作,则您的RaisePropertyChanged()方法可以累积已更改属性的列表(changesList)。您应该实现公共(可能是虚拟的)方法ApplyChanges(),它清除此列表并保存数据(如果您通过网络发布更改,请添加更多检查,以便您不会反复发送相同的数据)。还有公共财产bool IsChanged {get;返回changesList.Any() - 您可以使用此属性将“Apply”按钮绑定到。
对于你的情况:在复杂的构造函数中,调用ApplyChanges()来重置IsChanged状态,并且在复杂控件绑定到VM之后,也调用ApplyChanges() - 即使你知道用户还没有做任何事情。