我正在尝试使用 Catel 进行“肮脏”的实施。
我有一个视图模型,有一个[Model]
属性和一些[ViewModelToModel]
映射到它。
我添加了一个布尔成员_canGetDirty
,当设置为true
允许视图模型属性提示服务进行保存时。
所以我的逻辑是,如果模型属性更改,_canGetDirty
设置为false
,因此视图模型属性更改而不会变脏,并且当模型完成更改时,我们设置_canGetDirty
为true
新的。
问题是模型属性的PropertyChanged
事件在视图模型属性更改之前被调用,因此_canGetDirty
总是正确的,并且每当我加载新模型时都会调用我的服务进行保存。
如何解决这个问题?
public class MyViewModel : ViewModelBase
{
private IMyService _myService;
private bool _canGetDirty;
public MyViewModel(MyModel myModel, IMyService myService)
{
MyModel = myModel;
_myService = myService;
}
[Model]
public MyModel MyModel
{
get { return GetValue<MyModel>(MyModelProperty); }
set
{
_canGetDirty = false;
SetValue(MyModelProperty, value);
}
}
[ViewModelToModel("MyModel")]
public string Prop1
{
get { return GetValue<string>(Prop1Property); }
set { SetValue(Prop1Property, value); }
}
[ViewModelToModel("MyModel")]
public string Prop2
{
get { return GetValue<string>(Prop2Property); }
set { SetValue(Prop2Property, value); }
}
[ViewModelToModel("MyModel")]
public string Prop3Contains
{
get { return GetValue<string>(Prop3Property); }
set { SetValue(Prop3Property, value); }
}
#region Registering
public static readonly PropertyData Prop1Property = RegisterProperty("Prop1", typeof(string), null, PropertyToSaveChanged);
public static readonly PropertyData Prop2Property = RegisterProperty("Prop2", typeof(string), null, PropertyToSaveChanged);
public static readonly PropertyData Prop3Property = RegisterProperty("Prop3", typeof(string), null, PropertyToSaveChanged);
public static readonly PropertyData MyModelProperty = RegisterProperty("MyModel", typeof(MyModel), null, MyModelChanged);
#endregion
#region Property Changed Handlers
private static void MyModelChanged(object sender, PropertyChangedEventArgs e)
{
(sender as MyViewModel)._canGetDirty = true;
}
private static void PropertyToSaveChanged(object sender, PropertyChangedEventArgs e)
{
var vm = sender as MyViewModel;
if (vm._canGetDirty)
vm._myService.AskForSaving();
}
#endregion
}
编辑:关于 Catel 在这种情况下如何工作的一些解释。
注册属性更改:
我们注册将通知更新的属性RegisterProperty
:
public static readonly PropertyData Prop1Property = RegisterProperty("Prop1",
typeof(string), null, PropertyToSaveChanged);
最后一个参数是注册属性发生变化时调用的回调函数。
自动更新模型的属性:
我们将属性设置为模型:
[Model]
public MyModel MyModel
{
get { return GetValue<MyModel>(MyModelProperty); }
set
{
_canGetDirty = false;
SetValue(MyModelProperty, value);
}
}
此类包含一些属性(Prop1、Prop2、Prop3)。Catel 允许我们通过将它们映射到 ViewModelToModel 来自动从视图模型更新它们:
[ViewModelToModel("MyModel")]
public string Prop1
{
get { return GetValue<string>(Prop1Property); }
set { SetValue(Prop1Property, value); }
}