Catel嵌套控件中的CancelEdit,CancelViewModel和HasDirtyModel

时间:2014-04-18 19:57:58

标签: catel

我有一个窗口,包含一个嵌套控件NC1,它包含3个嵌套控件NC2实例。我有一个"重置" NC1上的按钮,用于复位NC1的值和NC1内的所有三个NC2。

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

我尝试在NC2的所有三个实例和((IEditableObject)nc1).CancelEdit()上显式调用((IEditableObject)nc2).CancelEdit()。虽然这完全重置,但只在NC1上执行CancelEdit并没有重置NC2模型。 (NC1的视图模型具有[模型]和[曝光(" NC2s")]的属性,这是NC1模型中的列表。

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

所有模型都源自ModelBase。 我该怎么做才能使HasDirtyModel变为假。

此问题适用于使用Catel 3.9的WPF应用程序

2 个答案:

答案 0 :(得分:0)

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

不幸的是,模型可以实现IEditableObject而无需从外部订阅订阅。这使得检查模型是否每次都回滚是不可能的(或者至少是性能成本很高)。这只能是"固定"通过跟踪完全克隆的对象图并比较当前对象图是否完全等于原始对象图。

这需要对视图模型上的每个模型进行完整的图形克隆,这对于性能成本太高(特别是考虑到ARM平台)。

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

答案 1 :(得分:0)

所以简单(我希望)的解决方案是在模型级别创建一个IsModelDirty属性。避免使用IsDirty,因为它不可重写并将其设置为false足以将模型再次设置为脏(即IsDirty变为true)。在模型中覆盖OnPropertyChanged并在其中设置IsModelDirty true。在我的情况下,由于我的控制流,不需要确保被更改的属性不是IsDirty。该框架已将其设置为True,并且框架或我都没有将其设置为False。在我的Model构造函数中,我将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注册的每个Model的IsDirtyFlag。