我在DomainContext.RejectChanges()中遇到问题,并在UI中反射(reflect)了回滚。这是我的情况。
因此,从本质上讲,在一个屏幕上有一个 FooViewModels 的列表框...当您选择一个项目时,将显示一个子窗口来编辑该特定 FooViewModel 。 FooViewModel 服务于列表框和子窗口。
编辑工作正常。子窗口中的更改会立即反射(reflect)在列表框中,因为更新 View 模型属性时,我正在调用 RaisePropertyChanged()。
但是,如果我执行 DomainContext.RejectChanges() ...,基础实体将回滚(所有更改均按预期还原)...但是 FooViewModel 并不知道已发生此更改,因此UI没有更新。如果我在第一个屏幕上的列表框中重新选择该项目,则将显示子窗口,其中包含回滚的更改(这是我想要的)。列表框仍然没有更新。
当我拒绝更改时,如果我为我更改的字段添加 RaiseProperyChanged(),则UI列表框会更新。
当基础实体被拒绝时,如何更新UI?以及如何不跟踪 View 模型的哪些属性已回滚?我只是想念一个简单的方法来完成这个任务。
最佳答案
您可以尝试的方法是在基础实体Foo
上使用PropertyChanged事件,以在FooViewModel
属性上触发RaisePropertyChanged传递。
因此做出一些假设(因此此代码有意义):
FooViewModel
中有一个私有(private)变量private Foo _foo;
private DomainContext _context;
FooViewModel
上有一个在域上下文中调用RejectChanges()
的方法。 像这样:
public void RejectChanges()
{
_context.RejectChanges();
}
FooViewModel
像这样:
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if(handler != null)
handler(this, new PropertyChangedEventArgs(propertyName);
}
好的,现在我们已经建立了,让我们看一下在域上下文上调用
RejectChanges()
时发生的情况。当您调用
RejectChanges()
时,它会从DomainContext
冒泡到其EntityContainer
,然后到该容器中的每个EntitySet
,然后到集合中的每个Entity
。到达该位置(以及
EntitySet
中)后,如果存在原始值,它将重新应用原始值;如果添加了该实体,则将其删除;如果删除了该实体,则将其添加。如果对值进行了更改,则将其应用回属性。因此,从理论上讲,应触发在实体属性中生成的所有RaisePropertyChanged()。
注意:我尚未对此进行实际测试。如果不是这种情况,那么所有这些都不起作用:P
因此,我们可以插入
Foo
实体的PropertyChanged事件,并在PropertyChanged
上引发FooViewModel
事件。因此我们的
RejectChanges()
方法可能如下所示: public void RejectChanges()
{
Func<object, PropertyChangedEventArgs> handler = (sender, e) =>
{
RaisePropertyChanged(e.PropertyName);
};
_foo.PropertyChanged += handler;
_context.RejectChanges();
_foo.PropertyChanged -= handler;
}
因此,我们将事件处理程序连接到
Foo
实体,该实体将使用属性名称在FooViewModel.RaisePropertyChanged
实体上更改的Foo
方法进行调用。然后,我们拒绝更改(这会触发属性更改),
然后我们解开事件处理程序。
缠绕很长一段时间,但我希望这会有所帮助:)
关于c# - 具有ViewModel和MVVM设计模式以及UI更新的RejectChanges(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9677374/