views:

469

answers:

1

I am currently writing an application to which the composite methodology fits like a glove.... almost!

I also need a way to navigate between views, including maintaining a journal for navigation backward and forward.

What is the best way to combine these two methodologies, on one hand the single Window based CAG shell with its UserControl derived views, and on the other hand the convenient NavigationWindow shell with its Page derived views and journal?

Thanks!

+3  A: 

You can display anything in a NavigationWindow, not just Pages. A simple way to make it work is to define in the NavigationWindow's resources a DataTemplate for each ViewModel you want to display. Bind the Content property of the NavigationWindow to a property of your main ViewModel, and you're done : changing that property will update the NavigationWindow content, and the appropriate DataTemplate will be picked automatically


UPDATE

I just looked at the code of a project of mine where I used a NavigationWindow. Actually I was mistaken, it doesn't work by binding the Content (or maybe it works, but that's not what I did). Instead I created a INavigationService interface, implemented by my App class, which handles the navigation by calling the NavigationWindow.Navigate method. That way, the navigation history is maintained by the NavigationWindow.

Here's an extract from my project

MainWindow.xaml :

<NavigationWindow x:Class="MyApp.MainWindow"
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  xmlns:vm="clr-namespace:MyApp.ViewModel"
                  xmlns:view="clr-namespace:MyApp.View"
                  Title="{Binding Content.DisplayName, RelativeSource={RelativeSource Self}, FallbackValue=The Title}"
                  Height="600" Width="800">
    <NavigationWindow.Resources>
        <DataTemplate DataType="{x:Type vm:HomeViewModel}">
            <view:HomeView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:CustomerViewModel}">
            <view:CustomerView />
        </DataTemplate>
    </NavigationWindow.Resources>
</NavigationWindow>

App.xaml.cs :

    ...

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        LoadConfig();

        MyApp.MainWindow window = new MainWindow();
        INavigationService navigationService = this;
        HomeViewModel viewModel = new HomeViewModel(navigationService);
        this.MainWindow = window;
        window.Navigate(viewModel);
        window.Show();
    }

When I need to navigate to another view, I just call the Navigate method with the ViewModel as a parameter, and WPF automatically picks the appropriate DataTemplate from the resources.

Thomas Levesque
That is a nice and simple solution, but it's a little bit too simple for my taste. Issues I have with it: Journalling, view lifetime management, view states, multiple views in navigation history, `PageFunction` feature (being able to call a view in a modal fashion).Or maybe I don't completely understand your solution, can you elaborate a little bit?
Aviad P.
Another concern would be the ability to develop views in a relatively indepedent way (decoupled from the shell). Basically, you're saying I should not use CAG at all, but rather use a workaround to make a regular `NavigationWindow` feel like CAG. But then I'm losing the advantages that CAG offers, dynamic loading of modules, independent module development, etc.
Aviad P.
Thanks for the additional details, Thomas, but I'm still not happy. What you're saying is 'create a regular navigation application, and implement the CAG parts yourself' - Meaning I need to provide for a unity container, dynamic loading of modules, dynamic creation of data templates for views, etc. I'd rather go the other way, use CAG and implement navigation and journalling myself. +1 for at least showing me what I **don't** want to do :-)
Aviad P.
Actually I've never used CAG, and I don't know much about it. My app is just a simple MVVM app, not using any particular framework, and the technique described above works just fine, but maybe it's not adequate for CAG...
Thomas Levesque