Pygmy
Pygmy

Reputation: 1268

Where to Create / Get / Cache the ViewModels?

First off, I'm new to MVVM, so please help me out on this :)

Suppose I have multiple views in my app. In my case, I have an editor view, and a browser view. Both of them have to work with a viewmodel of a "node" I'm editing.

So where does the viewmodel actually get created ?

Suppose the Editor is told to edit a certain node - It could create a new "NodeViewModel" and work with that. But at the same time, there's a NodeBrowserView, which allows people to shortcut-select a different node. Basicly - I need the EditorView to work with the same ViewModel as the BrowserView, so I need a generic "GetViewModelfor(X)" method.

So how is this supposed to work ? :)

Cheers :)

Upvotes: 4

Views: 1111

Answers (2)

tsells
tsells

Reputation: 2771

In cases like this I prefer to use a single main view model and have a "current item" that the view connects to instead. This is a lot easier to do instead of passing / creating new view models around each time a user clicks a different node / grid row / etc. I really see no need to a separate view model either when the same operations can be achieved in the overall view model. It reduces complexity and reduces the change of creating objects (view models) and leaving them hanging around because a reference to them was not released until the application is closed.

Upvotes: 0

k.m
k.m

Reputation: 31454

Both your editor view and browser view should operate on some kind of NodeViewModel. You shouldn't need separate view models just for the different view scenario.

Now, can you edit not-yet-shown-to-user node? If no (as in, user decides what is edited), view models should be created at the very first time their content needs to be presented to user. In most cases this would in some browser/details views, so that user can select element and then chose to edit it.

Edit:

Regarding your comment. NodeViewModel should be provided for editor view.

The providing part can be done for example via constructor injection or by setting view's data context manually. For example, when user browses all nodes in the browser view, he can double click on the list item and editor view will pop-up:

// this will probably be done in response to event
private void ListItemDoubleClick(object sender, EventArgs e)
{
    NodeViewModel currentItem = // extract current list item
    EditorView editorView = new EditorView(currentItem);
    editorView.Show();
}

Alternatively, if you want to avoid this kind of strong coupling between CompositeView and EditorView you can always use events, however it's not always necessary.

One more thing I was thinking of in terms of design would be adding extra view model, call it NodesListViewModel. How the program flow might look like:

  1. At application startup, get your nodes (be it from DB, file, service, anything)
  2. Create instance of NodeListViewModel which takes dependency on IList<Node> (list of node entities)
  3. NodeListViewModel will build and expose collection of NodeViewModel elements
  4. Create instance of your main program window, which uses composite view. It needs NodeListViewModel as its data context.
  5. Whenever user decides he needs to edit item, it's all ready. Browser has a list of all NodeViewModels, it can easily pick up current and pass it to dedicated view.

Upvotes: 1

Related Questions