1

I'm currently writing a rather small desktop application using the MVVM Approach. It also utilizes Entity Framework 6 for the database access. Right now, my top-level ViewModel instantiates the 'smaller' ones, and passes them the DbContext I'm using. The smaller ViewModels I use correspond to UserControls sitting in a separate TabItem each. But if I change something in the database in one tab and switch the tab afterwards, the UI isn't keeping up, logically, since there is no OnPropertyChanged("SomeObservableCollection") Happening.

I thought about just "refreshing everything inside" when a TabItem becomes active, but on one hand, I don't know how to do this (it would basically be doing OnPropertyChanged(..) for every UI-relevant property, right?), and on the other hand, it does seem neither elegant nor 'correct'.

What should I do about this? And is using one global DbContext even good practice? I read about short-lived DbContext instances being better, but I also found the opposite statement regarding desktop applications...

How do you handle this scenario? It can't be that rare actually, can it? Thanks!

InvisiblePanda
  • 1,589
  • 2
  • 16
  • 39
  • 1
    I 'm not sure to what extent exactly you will find it directly applicable, but I have written [an answer](http://stackoverflow.com/questions/10437241/mvvm-binding-to-model-while-keeping-model-in-sync-with-a-server-version/10445415#10445415) that seems relevant to your situation. – Jon Apr 29 '14 at 09:56

3 Answers3

2

You have to look at using a Messenger (MvvMLight) or EventAggregator (Caliburn.Micro).

So when your context has changed you pass the message about it and update your SomeObservableCollection so OnPropertyChanged("SomeObservableCollection") will be raised.

Veikedo
  • 1,453
  • 1
  • 18
  • 25
  • Or simply use events? Providing the related view models retain instances of eachother. – BenjaminPaul Apr 29 '14 at 12:42
  • @BenjaminPaul, another way to be done this. But using messengers is a little bit simpler in testing – Veikedo Apr 29 '14 at 13:00
  • and using messages decouples the viewmodels from each other. The viewmodels don't care where the message comes from. They just do what they are told to do when they receive that registered message. – ecathell Jun 10 '14 at 21:00
1

Might Help . I have done this in small project . any better solutions are welcomed.

**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 where we receive notification

  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
Eldho
  • 7,795
  • 5
  • 40
  • 77
1

Thats not an easy subject at all.

If you handle with a small amount of data and performance is not a problem for you, you could update your bindings every time the view gets loaded. Here you can see how to accomplish that.

A Problem if you do that is, that you have to do some extra logic for saving last selected items and reselect them after the view gets loaded.

Using a messenger could be an option too. But in my experience the messenger could make thinks messy if it is not implemented correctly. For example please dont use some magic strings as messeages.

Andre
  • 1,044
  • 1
  • 11
  • 23