Silverlight 3 style NavigationContext in WPF

Standard

 image

At the moment I’m experimenting with various user interface technologies.  Because the prototypes are working in parallel, I want to reuse code where possible.  With this in mind, I’ve created a couple of useful wrapper functions for navigation in both Silveright 3 and WPF that I thought I’d share.

 

In case you don’t know the Silverlight 3 Beta now has a navigation framework that works in a similar way to WPF’s Frame navigation feature.   To learn more about it, check our Jeff Poise’s great article Silverlight 3’s New Navigation Framework.

 

I brief, to navigate to a new page and pass a parameters you use a syntax like this in the code behind:

 

Me.NavigationService.Navigate(New Uri(String.Format(“/SomePage.xaml?someparameter={0}”,somevalue), UriKind.Relative))

 

In the loaded event of the page you’re navigating to, you use code like this:

 

Private Sub MyPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
     txtSomeTextbox.Text =  Me.NavigationContext.QueryString("someparameter")
End Sub

 

Nicer Navigating

I found the Navigate method above a little awkward, so in Silverlight I created a little helper function called “NavigateTo”, on page that makes the code a bit nicer.

 

Me.NavigateTo(“/SomePage.xaml”,”someparameter”,somevalue)

 

Here’s the implementation:

 

Imports System.ComponentModel
Public Module PageHelper
    <System.Runtime.CompilerServices.Extension()> _
   Public Sub NavigateTo(ByVal page As System.Windows.Controls.Page, ByVal navigationUrl As String, ByVal ParamArray arguments() As String)
        Dim lsUrl As String = navigationUrl & "?"
        Dim lbIsParamName As Boolean = True
        For Each lsArg As String In arguments
            lsUrl &= lsArg
            If lbIsParamName Then lsUrl &= "="
            lbIsParamName = Not lbIsParamName
        Next

        page.NavigationService.Navigate(New Uri(lsUrl, UriKind.Relative))
    End Sub

End Module

 

Nicer NavigationContext

 

I found Silverlight3’s NavigationContext quite nice to use.  Unfortunately this is not available in WPF.  I set about creating a helper function that would emulate this functionality in WPF.

 

WPF Navigation Helper

 

Here’s a WPF version of PageHelper that allows a compatible syntax with Silverlight3.  

 

Imports System.ComponentModel
Public Module PageHelper

    Private WithEvents moCurrentNav As NavigationService
    <System.Runtime.CompilerServices.Extension()> _
   Public Sub NavigateTo(ByVal page As System.Windows.Controls.Page, ByVal navigationUrl As String, ByVal ParamArray arguments() As String)

        '  Update Navigation Args
        Dim loNavigationUri As New NavigationContext

  If arguments.Length > 0 Then
            For i As Integer = 0 To arguments.Length - 1 Step 2
                 loNavigationUri.QueryString.Add(arguments(i), arguments(i + 1))
            Next

            End If

           
        loNavigationUri.Uri = New Uri(navigationUrl, UriKind.Relative)

        ' Strip the Xaml extension 
        Dim lsClassName As String = navigationUrl.Substring(0, navigationUrl.Length - 5) 
        ' Make my class name 
         Dim lsName As String = page.GetType.Namespace & "." & lsClassName 
        ' Instantiate the class 
        Dim loPage As Page = page.GetType.Assembly.CreateInstance(lsName) 
        ' Do the Navigation 
         page.NavigationService.Navigate(loPage, loNavigationUri)
    

        ' Store the current NavigationService so we can complete
        moCurrentNav = page.NavigationService

    End Sub
    <System.Runtime.CompilerServices.Extension()> _
Public Function NavigationContext(ByVal page As System.Windows.Controls.Page) As NavigationContext
        Return moLastNavContext
    End Function
    Private Sub moCurrentNav_Navigated(ByVal sender As Object, ByVal e As System.Windows.Navigation.NavigationEventArgs) Handles moCurrentNav.Navigated
        moLastNavContext = e.ExtraData
        moCurrentNav = Nothing
    End Sub
    Private moLastNavContext As New NavigationContext

End Module
Public Class NavigationContext
    Public QueryString As New Dictionary(Of String, String)
    Public Uri As Uri
End Class

 

I also have provided primitive support for cross-assembly navigation.

 

I hope someone found this useful, let me know.

 

 

Share this post :

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s