MVVM and window lists
I am writing an application that allows users to view data, and I want to use the FireFox interface style: allow the user to open as many windows as they want, each with as many tabs as they want. I also want to try and do this using the Model-View-ViewModel pattern as much as possible.
Opening a new tab should be easy enough to work in MVVM. Create an ObservableCollection TabViewModel, bind that collection to the ItemsSource of the TabControl, and then opening a new tab is theoretically as simple as adding a new TabViewModel collection to the collection.
Here's my question: is there a way to do the same for opening a new window? Ie, databind a ObservableCollection WindowViewModel for ItemsSource ... Windows app collection? ... so when I add a new WindowViewModel to the observable collection a new window is automatically opened? And then bind this to the application launch so that instead of setting the StartupUri, I just add the first WindowViewModel to the collection?
Since I can't actually databind Application.Windows, what would be the best way for the ViewModel layer:
- Add a new WindowViewModel and automatically open a new window;
- Remove WindowViewModel and automatically close the window.
- Remove the WindowViewModel from the collection if the user closes the window.
I could write my own object that monitors INotifyCollectionChanged and opens / closes windows in response to collection events, but I'm not sure if this is the best way - and if so, I'm not sure about the best way to bind it to the application. Anyone have any thoughts on the best way to do this?
a source to share
The point of MVVM is that the ViewModel should n't take care of itself (in detail) with how . The View will react to changes in the ViewModel.
One of the possibilities is a simple tracking algorithm in the View view of the CollectionChanged event in the ViewModel, creating and destroying Windows on the fly:
Dictionary<WindowModel, WindowView> _cache = new;
void WindowModelListChangedHandler(sender, args) {
switch(args.Action) {
case Add:
_cache[args.NewItem] = new WindowView(args.NewItem);
_cache[args.NewItem].Show();
break;
case Remove:
// ...
}
}
a source to share