| Comments

I got an email the other day about if there was a way to pass an object between the navigation pages in Silverlight 3.  The scenario was that the developer wanted to use the same data, but represent it visually in different ways.

Silverlight 3 introduces a new navigation framework in the runtime making it easier to navigate to different areas of an application and assist in ‘deep linking’ concepts for applications.  More resources:

At first my reaction was “no, we don’t allow that easily” but then I thought about it a bit and played around with a sample in the context of this developer’s use case.  Right now, the way you can quickly pass chunks of data to another page is via query string mechanisms.  So in my code I can say:

   1: myFrame.Navigate(new Uri("/foo.xaml?customerId=1234", UriKind.Relative));

And then in the navigated page something like:

   1: string customerId = this.NavigationContext.QueryString["customerid"];

This works fine for string/simple data.  In fact I could probably serialize a simple type and send it this way as well…but I don’t think that was the desired intent of this developer.  But if you think about the concept of the Frame, then you can start thinking about DataBinding techniques and how we can use the Frame as our container.  Allow me to think out loud…

Let’s use the default Silverlight Navigation Application template in the Silverlight 3 Tools for Visual Studio.  This will give us enough stub to work with.  If you look at MainPage.xaml you’ll see that the page has one Frame element in it:

   1: <navigation:Frame x:Name="Frame" Source="/Views/HomePage.xaml"
   2:       HorizontalContentAlignment="Stretch"
   3:       VerticalContentAlignment="Stretch"
   4:       Padding="15,10,15,10"
   5:       Background="White"/>

This is the core element that is going to receive navigation commands and change its content based on those commands.  Now in the Loaded event handler of MainPage, let’s grab some data.  I’m using a simple class here that just iterates a Person type (mainly so I can include it in the sample easily).  My Loaded event handler now looks like this:

   1: void MainPage_Loaded(object sender, RoutedEventArgs e)
   2: {
   3:     People p = new People();
   4:     List<Person> peeps = p.GetPeople();
   6:     this.Frame.DataContext = peeps;
   7: }

So you can see that I’m now setting the DataContext of the Frame element to my List<Person>.  So now let’s crack open some of the other pages.  Again, remember the scenario: same data, different views.  Open the Views/HomePage.xaml and let’s show a view of just a simple list of names.  I added a ListBox and just displayed the FullName property of my data:

   1: <StackPanel> 
   2:     <TextBlock Text="Name List" Style="{StaticResource HeaderTextStyle}"/>
   3:     <StackPanel Style="{StaticResource ContentTextPanelStyle}">
   4:         <ListBox x:Name="PeopleList" DisplayMemberPath="FullName" 
   5:             ItemsSource="{Binding}" />
   6:     </StackPanel>
   7: </StackPanel>

Notice that there is going to be no code here in the source file for HomePage.xaml.cs – we are using the {Binding} property for the ItemsSource…essentially trickling down the DataContext from the Frame.  Remember, that HomePage.xaml is essentially a child control of the Frame so it is aware of the DataContext.  Now let’s go into AboutPage.xaml for our more detailed view, showing a DataGrid of all the elements of the data:

   1: <StackPanel>
   2:     <TextBlock Text="Detail" Style="{StaticResource HeaderTextStyle}"/>
   3:     <TextBlock Text="Detail list of members with gender." 
   4:             Style="{StaticResource ContentTextStyle}"/>
   5:     <data:DataGrid ItemsSource="{Binding}"/>
   6: </StackPanel>

Again, no code here to retrieve the data or wire it up – using {Binding} to the DataContext again.  So now with one data fetch and binding to our navigation context (Frame) we can re-use that same object across different views and the result shows us different levels of detail.

View 1: simple listView 2: detail list

So at least that is one thought of how to share the information.  What do you think?  Obviously it will not work in all scenarios, but also remember you can have more than one navigation frame in your application too!  Here’s the sample code for these thoughts: SilverlightApplication32.zip

Hope this helps!

| Comments

A while back I pondered doing a “live” debug session with people who were/are working with Silverlight 2 and data access via services, etc.  I really like a live concept because it allows people to ask real questions and feels more conversational than a one-way presentation.  After some consideration, I’m not sure I could quite guarantee the environment I was looking for to accomplish this type of style.

confused man imageSo as a second best, I’ve set up a webcast: Troubleshooting Silverlight Data Access.  I hope to keep the question channel open during the webcast though and answer as many questions as possible.  I’ve seen many questions on forums, through emails, and all over the interwebs about people hitting certain pitfalls with Silverlight and data access.  Most of these are common scenarios and you need just a bit of “a-ha!” help to get you over the confusion stump.  That’s my aim.  I have set aside an hour (would have liked to do it sooner, but just time doesn’t permit right now) to tackle the most common things I’m seeing with data and Silverlight.  I’ll create the scenarios that get you stuck and show you what I do to help get you un-stuck from those moments.  Stop scratching your head any longer!

UPDATE: The webcast is now available online for playback.

We’ll look at tools you can use, how you can dig deeper into error messages, working with different types of data, etc.  I want to help!  Please leave your questions here on this blog post as a comment so that I can be sure to address the scenarios.  This isn’t a 1:1 debug session, so it will be hard to tackle the “hey, I’ve got this service from my AS/400 server exposed as a fitzer-valve service bus, which is able to be called from my Java front-end but doesn’t work in Silverlight: why not Tim?" questions, but I hope to help get you along the path of what to look for and to avoid the common mistakes.

Sound good?  I’m looking forward to it.  Again, please leave comments on this post so we can have the best possible session.  You can register for the webcast here.  I look forward to our time together :-).

Related Posts:

This work is licensed under a Creative Commons Attribution By license.