【问题标题】:How to "refresh" my ViewModels after database changes have been done in another ViewModel?在另一个 ViewModel 中完成数据库更改后如何“刷新”我的 ViewModel?
【发布时间】:2014-06-15 04:31:06
【问题描述】:

我目前正在使用 MVVM 方法编写一个相当小的桌面应用程序。它还利用 Entity Framework 6 进行数据库访问。现在,我的顶级 ViewModel 实例化了“较小”的 ViewModel,并将我正在使用的 DbContext 传递给它们。我使用的较小的 ViewModel 对应于每个位于单独 TabItem 中的 UserControl。但是,如果我在一个选项卡中更改数据库中的某些内容并在之后切换选项卡,那么从逻辑上讲,UI 跟不上,因为没有 OnPropertyChanged("SomeObservableCollection") 发生。

当 TabItem 变为活动状态时,我想过只是“刷新内部的所有内容”,但一方面,我不知道该怎么做(它基本上会为每个 UI 相关属性执行OnPropertyChanged(..),对吗? ),另一方面,它看起来既不优雅也不“正确”。

我该怎么办?并且使用一个全球性的DbContext 甚至是一种好的做法?我读到过短暂的DbContext 实例更好,但我也发现了关于桌面应用程序的相反说法......

您如何处理这种情况?实际上不可能那么罕见,不是吗?谢谢!

【问题讨论】:

  • 我不确定你会在多大程度上发现它直接适用,但我写了an answer,这似乎与你的情况有关。

标签: c# wpf entity-framework mvvm


【解决方案1】:

您必须考虑使用 Messenger (MvvMLight) 或 EventAggregator (Caliburn.Micro)。

因此,当您的上下文发生变化时,您将传递有关它的消息并更新您的SomeObservableCollection,因此OnPropertyChanged("SomeObservableCollection") 将被提出。

【讨论】:

  • 或者只是使用事件?提供相关的视图模型保留彼此的实例。
  • @BenjaminPaul,另一种方法可以做到这一点。但是在测试中使用 messengers 会简单一些
  • 并使用消息将视图模型彼此分离。视图模型不关心消息来自哪里。当他们收到注册的消息时,他们只会做他们被告知要做的事情。
【解决方案2】:

可能会有所帮助。我在小项目中做到了这一点。欢迎任何更好的解决方案。

**Viewmodel 1 Where changes occurs**

//database call  
string result = _dataService.Insert(data);
if(result=="Success")
{
   //notify viewmodels using default messenger instance
   MessengerInstance.Send(new NotificationMessage("notifycollection"));
}

我们收到通知的 Viewmodel 2

  public AssignTimeSlotViewModel(IDataService dataService)
    {
        // registering the notification 
        MessengerInstance.Register<NotificationMessage>(this, receiveNotification);
    }

   #region Messenger - receivers

    private void receiveNotification(NotificationMessage msg)
    {
        if (msg.Notification == "notifycollection")
        {
            /// Call Database to keep collection updated.

             // raise propety changed event if neccessary.
            // Do Something
        }

    }

    #endregion

【讨论】:

    【解决方案3】:

    这根本不是一个容易的话题。

    如果您处理少量数据并且性能对您来说不是问题,您可以在每次加载视图时更新绑定。 Here 你可以看看如何做到这一点。

    如果你这样做,一个问题是,你必须做一些额外的逻辑来保存最后选择的项目,并在视图加载后重新选择它们。

    使用信使也是一种选择。但是根据我的经验,如果没有正确实施,信使可能会使想法变得混乱。例如,请不要使用一些魔术字符串作为消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 2017-02-13
      • 2018-05-30
      • 1970-01-01
      • 2022-11-25
      相关资源
      最近更新 更多