| Comments

Are you a startup organization?  Perhaps your the next greatest Silverlight control vendor or have a great app?  I want to help.  If you’re a Silverlight startup (or any startup really for that matter), reach out to me.  If you haven’t heard of BizSpark yet, you’re potentially missing out.

If you meet the following criteria:

  • privately held company
  • in business less than 3 years
  • generate less than USD $1 million in revenue

you may qualify to get access to production licenses for development tools, platform products and server licenses for immediate use.  Take advantage of this and the Web Platform Installer to jumpstart your biz.  Read the details about BizSpark here: How BizSpark Works.

I’m one of the BizSpark Champs and want to help our startups out there – no matter what you are doing – be successful quickly.  Obviously I’d love to see some Silverlight/RIA goodness, so if you’re in that camp, be sure to let me know!  You can reach out to me via my contact information to start a dialogue.

| Comments

I’ve been playing around with the Silverlight 3 navigation framework some more (thanks for the comments/thoughts on the last post about sharing data).  I got a few emails about understanding how the navigation works and people coming up with interesting uses.  Let’s take a moment to explore two of these concepts: out-of-browser navigation and controlling your navigation in your app.

Navigation Basics

If you are using Visual Studio 2008 and the Silverlight 3 tools, you’ll notice that when you choose to create a new project (or perhaps you didn’t notice and this will be new to you) that you have an option to create a Silverlight Navigation Application which is a starter template for some basic navigation framework.  This isn’t required to use the navigation framework, but merely a starting point.

Silverlight Navigation Application template

Once you have this template and click on the different navigation buttons (and/or add your own as well) you’ll see that the content changes based on the event.  Additionally you should notice that the browser’s back/forward buttons integrate with this functionality and allow you to navigate back/forward using the browser controls as well, honoring the navigation context of the application.

Out-of-browser Navigation

So now you’ve finished your app, complete with navigation and also added the functionality to allow the application to be installed out-of-browser.  Yipee!  Your users install the application offline and boom, they call you and say “how do I go back to where I was?”  Well, ideally you’ve created an application that has good navigation points in it for them, but perhaps you want to add simple forward/back functionality while in out-of-browser mode similar to the in-browser buttons that come with their preferred Internet browsing software.

Guess what?  The navigation framework provides some APIs to help you that are a part of the Frame that you are navigating:

  • CanGoForward/CanGoBack
  • GoForward/GoBack

With these two you can emulate the same browser back/forward functionality.  Here’s an example using the default VS2008 navigation template.  In MainPage.xaml I’ve removed the branding information (your.application.name) and added the following (about line 30):

   1: <StackPanel Style="{StaticResource BrandingPanelStyle}" x:Name="JournalNav">
   2:     <Button Content="back" Style="{StaticResource PageLinkStyle}"
   3:         x:Name="NavBack" Click="NavBack_Click" />
   4:     <Button Content="forward" Style="{StaticResource PageLinkStyle}" 
   5:         x:Name="NavFwd" Click="NavFwd_Click" />
   6: </StackPanel>

The NavBack/NavFwd click functions look like this:

   1: private void NavBack_Click(object sender, RoutedEventArgs e)
   2: {
   3:     this.Frame.GoBack();
   4: }
   5:  
   6: private void NavFwd_Click(object sender, RoutedEventArgs e)
   7: {
   8:     this.Frame.GoForward();
   9: }

Now on the Frame that I’m using I added an event handler for Navigated that looks like this:

   1: private void Frame_Navigated(object sender, NavigationEventArgs e)
   2: {
   3:     NavBack.Opacity = Frame.CanGoBack ? 1 : 0;
   4:     NavFwd.Opacity = Frame.CanGoForward ? 1:0;
   5: }

And finally I’ve added a Loaded event handler to MainPage to handle the initial load:

   1: void MainPage_Loaded(object sender, RoutedEventArgs e)
   2: {
   3:     JournalNav.Visibility = App.Current.RunningOffline ? Visibility.Visible : Visibility.Collapsed;
   4: }

The end result is the application in-browser works fine and uses the browser software back/forward buttons.  When installed out-of-browser, you’ll notice that an application-specific “back” and “forward” links are created (only when they are applicable) and the user can still navigate the frame that way.

In browser:

Navigation in-browser

Out-of-browser:

Navigation out-of-browser

Simple enough and I would not have had to change anything about how I already used the navigation framework in my application.

Controlling your navigation history

The other comment I’ve got is if people wanted to have ultimate control over their history navigation and have some parts integrate with the browser and other parts not.  Let me introduce you to a property of Frame: JournalOwnership.  By default the setting is Automatic, which means that the frame integrates with the browser history journal.  Setting it to something else, like OwnsJournal for example, means that it will not automatically integrate and you are now responsible for that navigation. 

What this means is that you can have a frame that is independent of the browser navigation, but still leverage the power of the framework.  Let’s alter our default template and add one of our navigation pages to include it’s own navigation pages, but those we don’t want to be a part of the overall app. 

I’ve modified the MainPage to add a link to another page called SubNavigation.xaml which then looks like this:

   1: <StackPanel>
   2:     <StackPanel x:Name="JournalNav" Orientation="Horizontal">
   3:  
   4:         <Button Click="NavButton_Click" Tag="/Views/SubNav/SubNav1.xaml" Content="section 1" 
   5:                     Style="{StaticResource PageLinkStyle}"/>
   6:         <Button Click="NavButton_Click" Tag="/Views/SubNav/SubNav2.xaml" Content="section 2" 
   7:                     Style="{StaticResource PageLinkStyle}"/>
   8:  
   9:         <Button Content="back" Style="{StaticResource PageLinkStyle}" 
  10:             x:Name="NavBack" Click="NavBack_Click" />
  11:         <Button Content="forward" Style="{StaticResource PageLinkStyle}" 
  12:             x:Name="NavFwd" Click="NavFwd_Click" />
  13:     </StackPanel>
  14:     <navigation:Frame x:Name="SubFrame" JournalOwnership="OwnsJournal"
  15:             HorizontalContentAlignment="Stretch" Source="/Views/SubNav/SubNav1.xaml"
  16:                           VerticalContentAlignment="Stretch"
  17:                           Padding="15,10,15,10"
  18:                           Background="White"/>
  19: </StackPanel>

You’ll see it looks similar (just for demonstration purposes) and includes a Frame.  Notice the JournalOwnership property set to OwnsJournal.  Now I also have the same back/fwd links  and functions to control them (GoBack/GoForward) in this sample, but now since I (well, SubFrame) owns the journal, I’m responsible for the navigation.  So here’s what happens:

  • User navigates to app
  • User clicks “about” – browser history appended
  • User clicks “sub navigation” – browser history appended
  • Within the “sub navigation” page, user clicks “subnav 2” – browser history not updated
  • User clicks “back” within the “subnav 2” page – user is taken back to “subnav 1”

So By changing the JournalOwnership, I get the control to manage the journal navigation, but also have to remember that.

Summary

I hope these two little experiments help you look at the navigation feature in some new ways.  It’s really a great feature I’m having fun thinking about things out loud with you all and getting feedback and more ideas.  I can’t wait to see great Silverlight 3 applications built with our framework!

The code that I used for these experiments is available here: slnavexperiments1.zip.  You will need the Silverlight 3 developer tools to run this code.  You can obtain all those tools here at the Silverlight 3 beta information section.

Hope this helps!

| 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();
   5:  
   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

here is some csharp code:

 

<UserControl.Resources>
<ResourceDictionary x:Key="Collection" >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="dict" Source="/Resources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
public static T Load<T>(this string xaml) where T : UIElement
{
T child = null;

Canvas c = XamlReader.Load("<Canvas xmlns:sj='clr-namespace:Slidentity;assembly=Slidentity' "
+ "xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "
+ "xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>"
+ xaml + "</Canvas>") as Canvas;

child = c.Children[0] as T;
c.Children.Remove(child);

return child;
}
dfad

| Comments

In a few weeks I’ll be making the journey with Corrina and Arturo from ‘the states’ to Auckland, New Zealand for the WEB09 conference.  I’m honored to be joining some great folks like Ryan Stewart, Dan Rubin, Jarred Bishop and more.  I’m looking forward to learning a lot from this conference and having discussions about user experience and RIA development.

The team at WEB09 released an introductory video for the conference and I must say, someone put a lot of effort into this video: WEB09 Intro Video

I’m very much looking forward to my time at WEB09 and the time in New Zealand in general (I’ve never been, so if you have some advice, please share).  Hopefully some of you will be there and we can meet in person and chat about Silverlight! See you in a few weeks!


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