我目前正在使用MVVM方法编写一个相当小的桌面应用程序。它还利用Entity Framework 6进行数据库访问。现在,我的顶级ViewModel实例化了“较小”的ViewModel,并将DbContext
我正在使用它们传递给它们。我使用的较小的ViewModels对应于每个单独的TabItem中的UserControls。但是,如果我在一个选项卡中更改了数据库中的某些内容并在之后切换选项卡,则逻辑上UI不会跟上,因为没有OnPropertyChanged("SomeObservableCollection")
发生。
当TabItem变为活动状态时,我想到了“刷新内部的一切”,但一方面,我不知道如何做到这一点(对于每个与UI相关的属性,它基本上都在做OnPropertyChanged(..)
,对吧?),另一方面,它似乎既不优雅也不'正确'。
我该怎么办?并且正在使用一个全球DbContext
甚至是良好的做法?我读到了短暂的DbContext
实例更好,但我也发现了与桌面应用程序相反的声明......
你如何处理这种情况?它实际上不是那么罕见,可以吗?谢谢!
答案 0 :(得分:2)
您必须使用Messenger
(MvvMLight)或EventAggregator
(Caliburn.Micro)。
因此,当您的上下文发生变化时,您会传递相关信息并更新SomeObservableCollection
,以便{1}}被提升。
答案 1 :(得分:1)
可能会帮助。我在小项目中做到了这一点。欢迎任何更好的解决方案。
**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
答案 2 :(得分:1)
这根本不是一个容易的主题。
如果处理少量数据并且性能不是问题,则可以在每次加载视图时更新绑定。 Here你可以看到如何实现这一目标。
问题如果你这样做,你必须做一些额外的逻辑来保存最后选择的项目,并在视图加载后重新选择它们。
使用信使也是一种选择。但根据我的经验,如果没有正确实施,信使可能会使思维变得混乱。例如,请不要使用一些魔术字符串作为messeages。