【发布时间】:2017-05-19 18:11:58
【问题描述】:
我正在尝试使用 Catel 进行“肮脏”实施。
我有一个视图模型,有一个 [Model] 属性和一些 [ViewModelToModel] 映射到它。
我添加了一个布尔成员 _canGetDirty,当设置为 true 时,允许 viewmodel 属性提示服务进行保存。
所以我的逻辑是,如果模型属性更改,_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); }
}
【问题讨论】:
标签: c# wpf mvvm catel dirty-data