views:

108

answers:

4

I have a observable collection exposed as a property within a view model. The observable collection is loaded with objects from a data access layer (linq2sql).

When a new item is added to the database through another view model what is the best way to update the observable collection? Should I repopulate the observable collection with a query to the database or directly insert the new object into the collection?

Also I am still trying to work out how to get one view model to communicate with another one, but I've only been using mvvm for 3 days.

+2  A: 

Whenever a model object is saved into the database, send a message to the viewmodels including the saved model object. This could be achieved using the Messenger helper class in MVVM Light Toolkit

Veer
I ended up using this.
Shatterling
+2  A: 

Hi,

You can use a whole new class to manage notifications from one class to another. For the question regarding whether to load all entities or just add newly added entity, it really depends on the number of possible entities to load each time. If they are going to be very few, you can reload them each time, otherwise just add the newly added object to the collection.

Example:

class ViewModel1
{
    ObservableCollection<Object> entities;

    public ViewModel1()
    {
        EventsManager.ObjectAddedEvent += new EventHandler<ObjectAddedEventArgs>(EventsManager_ObjectAddedEvent);
        entities = new ObservableCollection<Object>();
    }

    void EventsManager_ObjectAddedEvent(object sender, ObjectAddedEventArgs e)
    {
        entities.Add(e.ObjectAdded);
    }
}

class EventsManager
{
    public static event EventHandler<ObjectAddedEventArgs> ObjectAddedEvent;

    public static void RaiseObjectAddedEvent(Object objectAdded)
    {
        EventHandler<ObjectAddedEventArgs> temp = ObjectAddedEvent;
        if (temp != null)
        {
            temp(null, new ObjectAddedEventArgs(objectAdded));
        }
    }
}

class ObjectAddedEventArgs : EventArgs
{
    public Object ObjectAdded { get; protected set; }

    public ObjectAddedEventArgs(Object objectAdded)
    {
        ObjectAdded = objectAdded;
    }
}

class ViewModel2
{
    public void AddObject(Object o)
    {
        EventsManager.RaiseObjectAddedEvent(o);
    }
}
decyclone
Much appreciated.
Shatterling
+1  A: 

As for the second part (how to teach view models talk to each other) I prefer to keep view models as decoupled as possible. Thus Event Aggregation or some kind of Message Broker seems to be natural choice.

The first part of the question is bit trickier, and I don't know correct answer. If Observable collection contains thousands of items I would try to choose an approach that doesn't involve complete reconstruction. Otherwise try the simplest and easiest solution you can come up with.

Anvaka
A: 

I use libraries I created that effectively allow one DataContext to save changes back to a parent DataContext and for a parent DataContext to notify its children that it just received changes.

With this functionality, I create a single master DataContext for my whole application, then for any modal windows with Ok and Cancel buttons or other parts of the UI that temporarily need their own "view of reality" I create child DataContexts. When the child DataContext writes back to the parent this causes all controls bound to objects in the parent to update and for the parent to broadcast the changes to all children so they can update too (or not, if they are in snapshot mode).

This solution took a while to code but works beautifully. I also use exactly the same mechanism to send changes to a parent DataContext on the server which is shared by other clients, so everyone has up-to-date data and giving me great caching performance. I even use it for communicating with my back-end data store.

Ray Burns