我在DomainContext.RejectChanges()中遇到问题,并在UI中反射(reflect)了回滚。这是我的情况。

  • 我有一个用于RIA服务的模型(实体)(我将其称为 Foo )
  • 我有一个ViewModel来包装 Foo 并对其进行扩展(我将其称为 FooViewModel )
  • 我有一个使用Binding的View,它使用 FooViewModel来显示和更新数据
  • 我有一个“外部” ViewModel,其中包含 FooViewModels
  • ObservableCollection
  • “外部” View 具有绑定(bind)到 ObservableCollection的列表框

  • 因此,从本质上讲,在一个屏幕上有一个 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
  • 上引发PropertyChanged事件

    像这样:
    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/

    10-12 04:48