2 回答
![?](http://img1.sycdn.imooc.com/545861b80001d27c02200220-100-100.jpg)
TA贡献1860条经验 获得超9个赞
有没有办法IsDirty在所有设置器之后将其设置为 false?
setter 不是自己调用的,必须有人调用他们。您应该确定是谁在这样做,并且要么阻止他在没有充分理由的情况下设置内容(首选),要么让他在完成后重置脏标志。
正如评论中所建议的,在设置器中添加断点并查看堆栈跟踪是查找设置来源的一个很好的起点......如果我不得不猜测,我会怀疑一些与导航相关的回调。
但是您应该尝试确保视图模型在构造函数之后初始化,这IsDirty实际上意味着“已通过视图更改”而不是“可能由用户更改,也可能只是延迟初始化的一部分”。
经过多次编辑后,我的编辑:
您应该修改架构以考虑视图模型的异步初始化。仅仅并行运行所有事情并希望得到最好的结果很少会奏效。
例如,您可以将属性设置为只读,直到初始化完成,然后IsDirty在.falseInitializeLookupValues
伪代码:
Constructor()
{
Task.Run( async () => await InitializeAsync() );
}
string Property
{
get => _backingField;
set
{
if (_isInitialized && SetProperty( ref _backingField, value ))
_isDirty = true;
}
}
private async Task InitializeAsync()
{
await SomeAsynchronousStuff();
_isInitialized = true;
}
private bool _isInitialized;
private bool _isDirty;
也许,您想将_isInitialized其作为属性公开给视图以显示一些沙漏,并使用 aManualResetEvent而不是简单的bool... 但您明白了。
![?](http://img1.sycdn.imooc.com/545847aa0001063202200220-100-100.jpg)
TA贡献1828条经验 获得超13个赞
由于这些SetProperty方法是可重写的,因此您可以注入一些自定义逻辑。当您需要验证对象是否已被更改时,这可能非常有用。
public class StatefulObject : Prism.Mvvm.BindableBase
{
private bool _isDirty;
public bool IsDirty
{
get => _isDirty;
private set => SetProperty(ref _isDirty, value);
}
protected override bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
{
var isDirty = base.SetProperty(ref storage, value, onChanged, propertyName);
if(isDirty && propertyName != nameof(isDirty))
{
IsDirty = true;
}
return isDirty;
}
public void Reset() => IsDirty = false;
}
请记住,当您初始化字段时,此IsDirty值为 true,因此在绑定之前,您需要调用该Reset方法将其设置IsDirty回 false,这样您就可以可靠地知道字段何时已更改。
请注意,如何处理这个问题在某种程度上取决于您。例如,您可以使用 Linq 执行此操作...
var fooDTOs = someService.GetDTOs().Select(x => { x.Reset(); return x; });
您还可以强制执行如下模式:
public class FooDTO : StatefulObject
{
public FooDTO(string prop1, string prop2)
{
// Set the properties...
Prop1 = prop1;
// Ensure IsDirty is false;
Reset();
}
}
- 2 回答
- 0 关注
- 117 浏览
添加回答
举报