0

我有一个窗口,其中包含一个嵌套控件 NC1,其中包含 3 个嵌套控件 NC2 的实例。我在 NC1 上有一个“重置”按钮,它应该重置 NC1 和 NC1 中所有三个 NC2 的值。

我已经尝试了几种重置按钮的实现,但都没有成功。在所有情况下,即使数据重置,HasDirtyModel 仍然为真。

我尝试在所有三个 NC2 实例和 ((IEditableObject)nc1).CancelEdit() 上显式调用 ((IEditableObject)nc2).CancelEdit()。虽然这会完全重置,但仅在 NC1 上执行 CancelEdit 不会重置 NC2 模型。(NC1 的视图模型具有 [Model] 和 [Expose("NC2s")] 的属性,它是 NC1 模型中的 List。

调用 CancelViewModel() 也会重置数据,但仍将 HasDirtyModel 设置为 true。

所有模型都派生自 ModelBase。我应该怎么做才能导致 HasDirtyModel 变为假。

此问题与使用 Catel 3.9 的 WPF 应用程序有关

4

2 回答 2

0

所以简单(我希望)的解决方案是在模型级别创建一个 IsModelDirty 属性。避免使用 IsDirty,因为它不可覆盖,并且将其设置为 false 足以再次将模型设置为脏(即 IsDirty 变为 true)。覆盖模型中的 OnPropertyChanged 并将 IsModelDirty 设置为 true。在我的情况下,由于我的控制流程,无需确保正在更改的属性不是 IsDirty。框架已经将其设置为 True,并且无论是框架还是我都没有再次将其设置为 False。在我的模型构造函数中,我将 LeanAndMeanModel 设置为 true。我在模型中覆盖 OnBeginEdit、OnEndEdit 和 OnCancelEdit。他们每个人的代码如下。

/// <inheritdoc />
protected override void OnBeginEdit (System.ComponentModel.BeginEditEventArgs e)
{
  base.OnBeginEdit(e);
  IsModelDirty = false;
  LeanAndMeanModel = false;
}/* method TLModelBase OnBeginEdit */

/// <inheritdoc />
protected override void OnCancelEdit (System.ComponentModel.EditEventArgs e)
{
  LeanAndMeanModel = true;
  base.OnCancelEdit(e);
  IsModelDirty = false;
  LeanAndMeanModel = false;
}/* method TLModelBase OnCancelEdit */

/// <inheritdoc />
protected override void OnEndEdit (System.ComponentModel.EditEventArgs e)
{
  LeanAndMeanModel = true;
  base.OnEndEdit(e);
  IsModelDirty = false;
  LeanAndMeanModel = false;
}/* method TLModelBase OnEndEdit */

最后,使用 GetAllModels() 覆盖 HasDirtyModel 以访问为 ViewModel 注册的每个模型的 IsDirtyFlag。

于 2014-04-22T17:06:50.013 回答
0

Catel 不支持 Cancel 和 HasDirtyModels 的组合。在内部,Catel 使用 INotifyPropertyChanged 订阅模型。一旦引发事件并且值不同,模型就会被认为是脏的。

不幸的是,模型可以实现 IEditableObject 而无需从外部订阅的选项。这使得检查模型是否每次都回滚变得不可能(或至少非常耗费性能)。这只能通过跟踪完全克隆的对象图并比较当前对象图是否完全等于原始对象图来“修复”。

这将需要对视图模型上的每个模型进行完整的图形克隆,这太耗费性能(尤其是考虑到 ARM 平台)。

一种简单的解决方案是自己跟踪重置状态。您是唯一知道何时调用 CancelEdit 的人。这意味着您可以在 VM 上设置 _hasDirtyModels,并在调用 CancelEdit 时将其重置。

于 2014-04-19T10:47:26.277 回答