UserControl/Page Navigation Architecture in WPF

I recently picked up WPF and decided to design a small, fractions-based game. Having used Adobe Flex for almost two years, I was surprised to see a lot of commonalities and similarities with WPF (like using XML-based control markup, and having styling options).

My requirement was to create a single-window application with a single entry-point; navigation moves to different screens. For example, I have a title screen, core gameplay screen, credits screen, etc. and need my main application to navigate between them.

Design

To implement this, I went with the following approach:

  • Dynamic Content Frame for Main Window: the main window would have a single frame; that frame would contain the current screen. Switching screens is as simple as changing the frame content to a different screen’s instance.
  • UserControl/Page per Screen: Each logical screen would be a separate subclass of Page, or UserControl (either works fine in my case).
  • Navigation Controller: The navigation controller “glues” the screens together and allows any screen to dictate navigation to another screen (while also encapsulating the implementation).

Implementation

Understanding how all the pieces work together, here’s the actual implementation.

MainWindow.xaml:






This is a window with the main content in the frame _mainContent. By default, it loads the title screen.

The title screen simply has a background image and a single button, “New Game,” which transitions to the core-game screen (i.e. starts the first level). The following code is in the button’s Click handler:


private void newGameButton_Click(object sender, RoutedEventArgs e)
{
NavigationController.NavigateTo(new CoreGameScreen());
}

Notice that we create a new instance of CoreGameScreen here. This means that our screens should be somewhat stateless (or else depend on the model class for state).

And NavigationController? Simply, it does this:


public static class NavigationController
{
private static Frame _mainContentFrame;

public static Frame Frame { set { _mainContentFrame = value; } }

public static void NavigateTo(object target)
{
_mainContentFrame.Navigate(target);
}
}

The controller allows any control on any screen to “signal” the main screen to change content. Like I mentioned earlier, this keeps things abstracted, since no screen needs to understand how changing screens works — only what to tell the NavigatonController.

Finally, although I chose to use Page for my base class, this sample code works equally well with UserControl. I personally have nothing constraining me either way, but if you do, you can use either. (Page seems to be a more natural, HTML-style mental concept, so I decided to use that instead.)

About Ashiq Alibhai, PMP

Ashiq has been coding C# since 2005. A desktop, web, and RIA application developer, he's touched ASP.NET MVC, ActiveRecord, Silverlight, NUnit, and all kinds of exciting .NET technologies. He started C# City in order to accelerate his .NET learning.
This entry was posted in Core .NET, WPF and tagged , . Bookmark the permalink.

3 Responses to UserControl/Page Navigation Architecture in WPF

  1. Jon says:

    Just what I was trying to do, but I was not sure if it was a good decision. Now it looks like it is 😉 Thanks!

  2. William Buchanan says:

    Thanks. I have been pulling my hair out trying to find a good way of doing this. This is a great solution to this problem, and definately the most elegant way I have seen of doing it!

  3. Wim says:

    Hi, I tried this (in VB-code). It sets the content of the _mainContentFrame in the NavigationController class, but it doens’t change the frame.
    Should there be some kind of link between the _mainContent of the MainWindow and the _mainContentFrame of the class ?

Leave a Reply

Your email address will not be published. Required fields are marked *