Silverlight Tips provides simple and useful tutorials and tips with real life examples, live demos and sample codes to download.
About authors:
Damon Serji
Damon Serji,
Silverlight developer working at Metia in London.
Gavin Wignall
Gavin Wignall,
Interactive Design Lead, working in design for over 10 years, the last 3 being in Silverlight.
Allan Muller
Allan Muller,
Developer, working on various types of Silverlight and WCF projects.

Metia 2010 WebAward for Best Advertising Website

This morning we received a delivery of the glorious shiny and cool WebAward trophy for Best Advertising Website award right to our door here at Metia in Leicester Square! This is for the project which I worked on at the beginning of this year and posted about on 28th January 2010. You can read my full post about this project at: The first interactive Silverlight banner ad in the world!.

The award is published on WebAwards website here: Metia wins 2010 WebAward for Mass Effect 2 Silverlight Campaign, and the actual project is available to see here: Metia Award Winning Silverlight Campaign for Mass Effect 2.

WebAward - Best of Industry 2010

As you may know, WebAward, sponsored by Web Marketing Association, are THE kind of awards any Internet marketing, online advertising, PR, and top web site design professionals would hope to get hold of. The WebAwards use seven criteria of Design, Content, Copywriting, Use of Technology, Innovation, Interactivity and Ease of use to evaluate award-winning websites from 96 industry categories.

 

Every year thousands and thousands of websites enter the WebAwards Competition and we at Metia not only were recognised as a #1 in our sector to receive the Best Advertising Website, but also managed to score about 20% higher than the category average, and this is a fantastic achievement that we are very proud of.

As the developer of this project, I am particularly delighted to have been a part of an exciting team with creative and motivated team members and would like to congratulate Dean, Mark, Tina, Stuart, Stephen, Sarah and Colin who like always worked hard to deliver an outstanding result.

Posted by Damon Serji on 8. October 2010 15:34 under: Silverlight News
 with 2 Comments

In my previous posts I explaind how to use Google Analytics in Silverlight to track different information about users interaction with your Silverlight application.

One of the things you want to include in your tracking report is how many users who visited your site had Silverlight installed and how many didn’t. In addition, you might want to go in deeper details and find out more about users who didn’t have your required  Silverlight plug-in on their computers:

- how many had an older version of Silverlight – and which version did they have
- how many had/didn’t have a Silverlight compatible platform
- haw many of users without Silverlight plug-in clicked on “Download Silverlight plug-in” that you provided
- how many didn’t download the Silverlight plug-in and continued interacting with the “none-Silverlight” version of the application that you provided (if you provided any)

The source code for this project is available for download from CodePlex.

You can capture all above details and add to your analytics report.

Doing above tracking requires you to A. Find the required information about user, and B. Send them to your analytics software.

You can find all information about the user Silverlight support from Silverlight.supportedUserAgent.js file which is provided by Microsoft. You can download Silverlight.supportedUserAgent.js from Microsoft’s website.

However in order to send the right data to Google Analytics/Webtrends (or any other analytics software) you need to modify this file slightly to send the information when necessary:

1. add Silverlight.supportedUserAgent.js to your project
After downloading the Silverlight.supportedUserAgent.js file, add it to your Web project and call if from your Default.aspx (or any page that hosts your Silverlight application). You can call this file from the header, but just make sure it is called after your Tracking.js file (your tracking code).

2. add tracking code to Silverlight.supportedUserAgent.js
If you open this file and have a look, you will quite quickly notice there are a few if-else statements which checks different browser and OS to see which is the user using. Off course it depends how you like your report to be generated and what you would like to capture, but this is what I have done:

At the end of “if (slua.OS != 'Unsupported')” statement and just before the final closing curly bracket, add the following tracking code:

trackEvent("SilverlightApplication", "Platform supports Silverlight", "OS: " + slua.OS + " - Browser: " + slua.Browser);

Above code could generates a similar report to this:

Category: SilverlightApplication
Action: Platform supports Silverlight
Label: OS: Windows – Browser: IE5

So by seeing above report I know how many users did support Silverlight and what platform where they using.

Find and modify the “if (version == '2.0')” and “else if (version == '1.0')”  statements at the bottom of the page and change them to include tracking code like this:

if (version == '2.0') {
    trackEvent("NoneSilverlight", "Unsupported silverlight", "Silverlight Version: 2.0");
    return (supUA && (slua.OS != 'MacPPC'));
}

else if (version == '1.0') {
    trackEvent("NoneSilverlight", "Unsupported silverlight", "Silverlight Version: 1.0");
    return (supUA && (ua.indexOf('Windows NT 5.0') < 0));
}

Now you know if user had a different version of Silverlight, and can drill down in the report to find out which version did they have.

3. If your Silverlight application was loaded
Since it is not clear from above report if user actually saw your Silverlight application you can add the below code:

In your Silverlight object add the following parameter:


<param name="onload" value="onSilverlightLoad" />

And then add the following java script code to your Default.aspx page:
function onSilverlightLoad(sender) {
    trackEvent("SilverlightApplication", "Platform supports Silverlight", "SilverlightApp was loaded");
}

This piece of code will be loaded every time your Silverlight application is loaded.

4. if user interacts with the none-Silverlight version of your site/application
if (and you must always) prepared a none- Silverlight version, using above method you should now have a good idea on how to send the tracking code to your analytics software if Silverlight was not loaded for any reason and the user carries on interacting with your none- Silverlight version.

Hint: to add none Silverlight version you can add your HTML inside the <object> tag and right after the last <param> tag. Any code or text before the </object> will be displayed when you don’t have Silverlight installed/enabled.

And to send the tracking on i.e. links, add it to your onload or similar function/event.

5. Call CheckSupported()function
Finally, add this function to your page:

function CheckSupported() {
    var tst = Silverlight.supportedUserAgent();
    if (tst) {
        return true;
    }
    else {
        return false;
    }
}

And now call it from your Default.aspx just before to </body> tag. i.e.:


<script type="text/javascript">
    CheckSupported();
</script>   
</body>

Posted by Damon Serji on 10. February 2010 13:24 under: Intermediate
 with 1 Comments

MassEffect2-Screenshot - Expanded viewExpanded view of Mass Effect 2 Silverlight banner

Today I am very excited to say we at Metia are at the very final stage of launching the world’s first interactive and expandable banner ad developed using Microsoft Silverlight 3.0 technology.

This Silverlight banner, which is going to be published on Tech and Gadgets page of MSN UK this afternoon (28th Jan 2010) and then published and remain on MSN UK homepage for a few weeks from tomorrow, has been developed to launch Electronic Art’s new game: Mass Effect 2.

MassEffect2-Screenshot - Minimized viewMinimized view of Mass Effect 2 Silverlight banner on MSN's homepage

As the developer of this project, I am particularly excited about launching this because apart from the fact that this is the first Silverlight banner in the world, it also uses cool Silverlight features such as Deep Zoom and Smooth Streaming. The banner has been designed to give the same exciting and lively feeling as the game by using some graphics from the game, and most importantly the creativity of our interactive designers as well as everybody else involved in this project at Metia, to add the essential touches to the user experience.

So some rather technical facts:

At first glance you might think how did Microsoft allow a banner with HD quality video and high resolution images, 1280×720 and 1920×1200 to be precise,  to be displayed on their MSN homepage, surly this is going to slow down the loading time for their homepage? Well it could slow the loading time down because the content of the banner all together is about 600MB! Yet, the answer is NO, and the reason is because the size of initial download banner is only about 40kb!

Basically, there are two .xap files for this banner: footprint and content. The footprint is the preloader .xap file that gets downloaded when loading the page and is 40kb, and the content .xap file, which is about 600kb, is the one that contains UI elements and dlls. All other contents including videos and images are streamed or downloaded seperatly in the background when needed. Seriously, the banner is supper fast.

So the banner is quite smart enough to not throw all content including Mass Effect 2 screenshots and many high-resolution images for your desktop wallpaper to your computer when you don’t actually want them. Instead, it starts downloading content at different stages according to the user’s behaviour, i.e. it guesses what content is the user going to see next and starts downloading it in the background, so when the user opens the content he/she is more likely to see the actual content instead of the loading bar. The amazing Smooth Streaming has also made it possible to download HD quality videos including Mass Effect 2 trailer without leaving the user waiting for hours!

I am very pleased to have experienced working on this exciting project, with exciting people, for an exciting client, and for an exciting event! The banner is going live this afternoon, so make sure you visit Tech and Gadgets page of MSN UK and download Mass Effect 2 wallpapers!

Mass Effect 2 screenshot

Mass Effect 2 screenshot

 

Mass Effect 2 screenshot

Mass Effect 2 screenshot

 

Posted by Damon Serji on 28. January 2010 06:16 under: Silverlight News
 with 4 Comments

As you may be aware, Google Analytics does not track any actions such as click and etc from inside Silverlight applications. To overcome this issue and track the actions made by users on a Silverlight application we need to manually report to Google the actions. We do this using “Event Tracking” feature on Google Analytics.

Above screen shot shows how the data show in Google Analytics once they are captured in Event Tracking. In the screen shot: Homepage, Home – video player and Products page are categories. Each category then has a list of Event Actions and each action could have a label to provide more details about that action, for instance you could have: ‘Homepage’ > ‘Clicks’ > ‘Logo Image’, which displays how many times the ‘Logo Image’ was clicked from the homepage of the site.

The process of tracking actions in Silverlight is very simple, it consists of capturing the actions and passing them to Google Analytics using a JavaScript function that Google provides us in their tracking code.

The first thing I would do in setting up tracking for my Silverlight application is to create a separate class in the main Silverlight project to managed the all tracking code. I then can use this class everywhere within my application and pass to it the required parameter for tracking. This way if I decided to change something in my tracking code, or use a complete different application for my tracking i.e. Webtrends, I then only need to change my code in one place and the rest of code remains as before.

1. create Tracking class

namespace SilverlightGoogleAnalytics.Tracking
{
    public class Tracking
    {
    }
}

A. declare some private variables for passing required parameters to the analytics:

private string category;
private string resourceLabel;
private string groupType;
private string action;
private static Tracking _instance;

B. create an instance of the Tracking class as a property

public static Tracking Instance
{
    get
    {
        if (_instance == null)
        {
            _instance = new Tracking();
        }

        return _instance;
    }
}

Instance is a static public variable that holds a reference to the Tracking class itself. You will see later how we use this property to access its Tracking’s public methods.

C. create a public method to receive parameters and pass to the analytics:

public void Track(string trackingCategory, string trackingResourceLabel, string trackingAction)
{

    category = trackingCategory;
    resourceLabel = trackingResourceLabel;
    action = trackingAction;
    SendTracking();
}

public void Track(string trackingCategory, string trackingAction)
{
    category = trackingCategory;
    action = trackingAction;
    resourceLabel = "";
    SendTracking();
}

The Track methods (note they both are called Track but have different signatures) take the tracking data: category, resourceLabel and action.

D. send the data to “trackEvent” JavaScript function
now that we have the tracking information we simply call a private method which sends the data to our JavaScript function (see step 2) using Invoke method for being sent off to Google Analytics:

private void SendTracking()
{
    HtmlPage.Window.Invoke("trackEvent", category, action, resourceLabel);
}

We don’t need to do anything else with this class, from now on we can simply use this track whenever we need to pass some tracking data to Google Analytics.

2. JavaScript function to pass parameters to Google Analytics
this is the code we need for passing the data to Google Analytics to save it as an event:

function trackEvent(category, action, opt_label, opt_value) {
    pageTracker._trackEvent(category, action, opt_label, opt_value);

}

Here I added this to a separate JavaScript file called Tracking.js, but you can also add it straight to your html/asp page inside script tags.
The default script that Google provides you for the analytics remain as they are.

3. Calling Tracking class from your code and passing tracking values
first create a private variable to hold a reference to your Tracking class:

private Tracking.Tracking tracking;

Now initialize your variable in your constructor or Loaded method:

tracking = new SilverlightGoogleAnalytics.Tracking.Tracking();

Now you can call the Track methods within Tracking class anytime needed. i.e.:

tracking.Track("SilverlightApplication", "Loaded");

Here I called the Track method within tracking that takes two parameters: Category and Action. I could also pass another parameter (resource label) for instance:

tracking.Track("Homepage", "Click", "ClickButton");


Improving your code:
The above code works perfectly fine, however this was a small project, if you were dealing with a much bigger scale project then you wouldn’t want to type in the category, action and resource label every time you have to pass the parameters because you could end up with inconsistent data or typo errors.

One solution to this is to use Enum variables for either category, action or resource label. So whenever you have to pass a action you just select it from the list of available actions and if it wasn’t there you can add it to the list so next time you can use the same action and not end up with an inconsistent report like: “Homepage > ClickButton > Clicked” and “Homepage > ClickButton > Mouse Click”

1. create a new class in your Silverlight project and call it Enums.

2. create required enum types

namespace SilverlightGoogleAnalytics.Enums
{
    public enum TrackingCategories
    {
        SilverlightApplication,
        Homepage
    }

    public enum TrackingGenericLabels
    {
        ClickButton
    }


    public enum TrackingActions
    {
        Click,
        Load
    }
}

3. use the created enum types to pass values

tracking.Track(Enums.TrackingCategories.Homepage.ToString(), Enums.TrackingGenericLabels.ClickButton.ToString(), Enums.TrackingActions.Click.ToString());

Posted by Damon Serji on 26. January 2010 10:29 under: Intermediate
 with 2 Comments

To set the margin or Canvas of an object from the code you can use SetValue() which is a built-in method. SetValue() takes a DependencyProperty such as a Button, and a double value.

Example:

myButton.SetValue(Canvas.LeftProperty, myPoint.X);

In above example ‘myButton’ is a Button on the xaml, and myPoint is a variable of type Point which we use the X value of.

Posted by Damon Serji on 11. January 2010 18:36 under: Basic
 with 0 Comments

Before I started writing this post I had a quick search on the internet about Silverlight Preloader (Silverlight progressbar) and noticed a few good posts that already exist and explain how to do this.

However, one thing I noticed from most of the tutorials about creating Silverlight progressbar is that they all replace the standard Silverlight preloader animation with a simple rectangle progressbar! Although displaying your logo with a standard progressbar in shape of rectangle is much better and professional than leaving the standard Silverlight preloader to be displayed, but I think it is not that cool!

To test this project I added a large file to the project in order to slow down the process of loading for us to see the effect. To view the live demo click here.

The code can be downloaded from CodePlex here.

As a result, I want to explain how to take your logo and with a bit use of maths do something cool to it, like filling it with color to display the progress of loading.

1.  Add new xaml and js files to your Web project
this xaml file will include your custom progress bar, you can call this anything you like, here we call it preloader.xaml. To add a new xaml file: right click on your .Web project from the menu find ‘Add’ and click on ‘New Item...’, from the left side (Categories) select ‘Silverlight’, and then from the right side (Templates) choose ‘Silverlight JScript Page’. Once you add the xaml file Visual Studio will add a new .js file for you too.

2. Add splashscreensource and onSourceDownloadProgressChanged parameters to your Silverlight object

on your Default.aspx, or any page that hosts your Silverlight application (in our case SilverlightPreloaderTestPage.aspx), add the splashscreensource parameter i.e.:


<object data="data:application/x-silverlight," type="application/x-silverlight"
id="SL">
    <param name="splashscreensource" value="loading.xaml" />
    <param name="onSourceDownloadProgressChanged" value="onSourceDownloadProgressChanged" />

The first parameter simply loads the loading.xaml while loading the main components of the Silverlight application.

The second parameter calls the onSourceDownloadProgressChanged  function from or preloader.js file.

3. Create a new progress bar in preloader.xaml using Blend
Since we want to fill a logo or a shape with color instead of just creating a rectangle progressbar, we need to draw the shape manually in Expression Blend. You might notice Blend doesn’t open the preloader.xaml file from our .Web project. To solve this issue I simply open a new xaml file in Blend and once I am happy with my changes I copy and paste the code to my preloader.xaml file.

To demonstrate the filling of a shape we need to use Path Clipping technique. Basically we need to create a rectangular Canvas and then cut the shape we want out from it. Then we can move another coloured rectangular, which is inside the canvas but positioned outside it by adding a high margin to it, to the left/right/up/down towards inside the canvas according to the percentage of loading. This way user will see the shape we draw earlier getting filled with color as the percentage of loading increases. To learn about Path Clipping visit Clipping paths in canvas using Expression Blend by Gavin Wignall.

4. Do the calculation in Java Script file
copy this code to your preloader.js file:

function onSourceDownloadProgressChanged(sender, eventArgs) {
    if (sender.findname("loadingStatus") != null) {
        var loaded = Math.round(eventArgs.progress * 10) / 10;
        sender.findName("loadingStatus").Text = "Loading: " + (Math.round(eventArgs.progress * 1000)) / 10 + "%";
        var newValue = 79 - (79 * loaded);
        sender.findName("LoadFill")["Canvas.Top"] = newValue;
    }
}

onSourceDownloadProgressChanged is the name of function which we call from our object in .aspx page (<param name="onSourceDownloadProgressChanged" value="onSourceDownloadProgressChanged" />).

loadingStatus is a name we have given to a TextBlock in our preloader.xaml. Here we find the TextBlock loadingStatus and then assign the current loading percentage to it.

eventArgs.progress  is a very long number like 0.3452345234232 and shows the percentage of loading, 1 is 100%. So we need to change this to something like 34.5 and 100 as 100%. To do this we first multiply eventArgs.progress  by 1000, this way we get 345.2345234232 and to remove the .2345234232 we use Math.round()function which is a Java Script built-in function. Now we should have 345. To get 34.5 which is the actual percentage of loading we simple divid

e the number by 10. At the end we add a bit of text to the result and insert it to our loadingStatus TextBlock.

In order to show our logo is getting filled by color we need to move the rectangular inside by changing its “Canvas.Top” property which acts just like Margin. As we want to keep the rectangular outside the visible area we position it 79 pixels, which is just the actual height of our rectangular, away from the top, so it sits just below the visible area.

If you follow the maths as I explain above you will understand that ‘loaded’ variable will have a value like 0.34 (this time we multiplied it by 10 instead of 1000). Lets say if we had 99 percent loaded then the ‘loaded’ variable would have a value of 0.99. times that by 79 and you get 78.21, now if we follow the equation: 79 – (78.21) =  0.79. If we set the Canvas.Top to 0.79 then our clipped area will be almost completely filled with color because the rectangular is sitting right at the top and that is exactly what we wanted to achieve.

Please note, if your rectangular is larger or smaller than 79 pixels you need to change both 79 to actual height of your rectangular to get this working correctly.

Posted by Damon Serji on 30. December 2009 12:47 under: Intermediate
 with 9 Comments

Sometimes you need to cut a shape out from your canvas to produce a special effect by showing another object from behind the canvas appearing in the clipped area. This mainly is used in making animations to for instance display a text appearing in the clipped area.

In order to achieve this all you need is a canvas, another object inside the canvas, i.e. text or a rectangular to work as a color panel, and a path in your desired shape:

1. Add a canvas to your page

2. Add a rectangular inside the Canvas and fill it with a color

3. Draw a path

make sure you clicked on the LayoutRoot level before drawing the path, so your path doesn’t appear inside the canvas. You can draw a path using Pen tool. Select the Pen tool from tools panel and click on different places on the page to see the shape been drawn, to end the path click on the start point.

4. Clipping the path out from the canvas
you can choose which object to be clipped from the other by the order of selecting them. In this case we want our shape which we created using path method to be clipped from the canvas. Therefore, we need to click and select our path first, and then holding the Ctrl button on the keyboard click on the canvas.

We should now have both our path and canvas selected. Go to ‘Object’ menu in Blend and from ‘Path’ click on ‘Make Clipping Path’ (shortcut key is Ctrl + 7).

Now your canvas should have a hole in the shape you draw earlier using the Pen. So by moving the rectangular inside the canvas you will be able to notice the clipped area appearing when the rectangular or text is on the same position and disappearing when we move the rectangular or text to outside the clipped area.

Posted by Gavin Wignall on 30. December 2009 11:33 under: Intermediate
 with 2 Comments
Get Microsoft Silverlight  Silverlight pagination

Pagination (DataPager) is a built-in control in Silverlight 3.0. You simply bind your data to the DataContext through a PagedCollectionView variable.

PagedCollectionView is a class that could store collection of your data with IEnumerable interface. Through this class you are then able to use cool features such as sorting, filtering and paging functionalities.

To test pagination in this post I created a class of type “Contact” to store name, surname and tel number for each contact.

public class Contact
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public int Telephone { get; set; }
}

To get a better visual and have different fields display for each of my contacts I created a ContactTemplate.xaml. This simply contains the template for each of my contacts:


<Grid x:Name="LayoutRoot" Height="50">
    <TextBlock Text="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="19" />
    <TextBlock Text="{Binding Surname}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="100,2,0,19" />
    <TextBlock Text="Tel:" Margin="0,17,0,6" HorizontalAlignment="Left" />
    <TextBlock Text="{Binding Telephone}" Margin="25,17,0,7" />
</Grid>

In my Mainpage.xaml I use an ItemsControl to list all contacts that have created using Contact class, and since I want each contact to be displayed within my ContactTemplate I display a reference to the ContactTemplate.xaml page and bind each contact to that:


<ItemsControl x:Name="Contacts" ItemsSource="{Binding}" >
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Local:ContactTemplate />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

To create a reference to the ContactTemplate.xaml you first need to create a namespace in your MainPage.xaml that refers to the project which ContactTemplate.xaml exists (the same project in our case). So don’t forget to add this to the top of the MainPage.xaml in order for your above code to work:


xmlns:Local="clr-namespace:SilverlightPagination"

Last thing we need to do in the MainPage.xaml is to add a reference to the pagination control (DataPager):

First add the reference:


xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

Now add the control:


<data:DataPager DisplayMode="PreviousNext" Margin="0,0,0,4" HorizontalAlignment="Center" Source="{Binding}" NumericButtonCount="{Binding Value, ElementName=numericButtonCount}" AutoEllipsis="{Binding IsChecked, ElementName=autoEllipsis}" IsTotalItemCountFixed="{Binding IsChecked, ElementName=totalItemCountFixed}" />

And to get it working your MainPage.xaml.cs should look something like this:

private List<Contact> allContacts;

public MainPage()
{
    InitializeComponent();
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    allContacts = new List<Contact>();
    AddData();

    PagedCollectionView pcv = new PagedCollectionView(allContacts);
    pcv.PageSize = 6;
    DataContext = pcv;
}

private void AddData()
{
    for (int i = 0; i <25; i ++)
    {
        Contact contact = new Contact();
        contact.Name = "DummyName " + i;
        contact.Surname = "DummySurname " + i;
        contact.Telephone = 020711111 + i;

        allContacts.Add(contact);
    }
}

In summary, AddData() creates some contacts so that we can test this project, and the rest happens in the MainPage_Loaded. As I explained at the beginning of this post, if you add your list of data to a variable of type PagedCollectionView then you can use the pagination feature of this class. Set the page size, and set the DataContext of the page to your PagedCollectionView variable. The DataContext simply binds your data where ever it is asked to down your code (even in your ContactTemplate.xaml page that you had already added in the ItemsControl.

Posted by Allan Muller on 14. December 2009 19:33 under: Intermediate
 with 1 Comments

If you want to play music or a short sound clip in Silverlight here is what you need to do:

1. Your sound file
First, make sure you sound file is MP3 or WMA format as other formats are not supported.

Save your file to ClientBin folder (where your xap file gets coppied when buiding the project)

If you dont want to store your file to the ClientBin folder do this: from Visual Studio right click on the sound file and select Properties. Now in Properties window change Build Action to Resource. This ensures the file gets copied to the ClientBin folder during execution.

2. Add a MediaElement in your Xaml file


<MediaElement x:Name="SoundClip" Source="boing.mp3" Volume="1" AutoPlay="False"></MediaElement>

set the Source to be the name of your file and AutoPlay to False so it can be played at click of a button.

Also add a button to play the sound when clicked:


<Button x:Name="PlaySound" Content="Play Sound" />

3. play the sound
in your code behind add this to the Click event of your button:

SoundClip.Play();

If you have any questions please visit Silverlight Forums here: http://silverlightforums.com/showthread.php?p=2080#post2080

Posted by Allan Muller on 10. December 2009 13:16 under: Basic
 with 1 Comments
Get Microsoft Silverlight  Silverlight Deep Linking.

This post is an update to the previous post I have done about Silverlight Deep Linking. So for details and to see previous code visit Basic Silverlight Deep Linking.

Download:
As usual, you can download the complete project from CodePlex site here.

Questions and answers:
For updates and any issues visit the specific thread regarding this post at Silverlight Forums: http://silverlightforums.com/showthread.php?t=1425

Basically, we need to use a built-in class called “NavigationFailed” from our Frame control to fire the event when user tries navigation to a none-existent page.

Here I demonstrate two ways of handling the error exception and displaying a friendly error message.

  • Using an error template page
  • Using a child window to display a popup message for the error

Here are 3 steps to get this working with error template page:

1. Create Error404.xaml and add it to UriMapper
add a new page to your Silverlight project and call it Error404 as it will only be used for the Error 404  or “Page not found” error.

Now, in your App.xaml add the error page to your Navigation UriMapper so the application can navigate to it when needed:


<Nav:UriMapping Uri="Error" MappedUri="/Error404.xaml" />

2. Add “MainFrame_NavigationFailed” method in MainPage.xaml.cs
in your MainPage.xaml.cs and in your constructor or Loaded method, add NavigationFailed event handler to your Frame control (MainFrame):

MainFrame.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(MainFrame_NavigationFailed);

If you use the Visual Studio’s snippet/shortcut it will automatically create the method for NavigationFailed event for you. Otherwise, add this method:

private void MainFrame_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
{
    MainFrame.Navigate(new Uri("Error", UriKind.Relative));
}

3. Handle the exception
although the above code looks find and seems to be working, If you run it you get the following exception error:

System.ArgumentException:
Navigation is only supported to relative URIs that are fragments, or begin with '/', or which contain ';component/'.

To fix this, you need to tell the Frame control (MainFrame) that this exception is being handled. So add this to your MainFrame_NavigationFailed method:

e.Handled = true;

Now if you try to change the URL to a page that doesnt exist you should get to see the Error404.xml page.

Using Child Window

To do this using Child Window all we need to do is to show the Child Window which we had created before (for more information about creating and showing a Child Window see my post: Passing value from Child Window to parent window).

1. Create a new Child Window (ErrorPopup.xaml)
add this file to your Silverlight project. Since we could use this for other errors too I tried to called it something more generic.

2. Add error property and placeholder to ErrorPopup
Since we want to be able to pass different error message to our popup control in the future, we add a TextBlock in the ErrorPopup.xaml, and we also add a property to our control (in ErrorPopup.xaml.cs) to receive the error message and display it in the TextBlock.

In ErrorPopup.xaml:


<TextBlock x:Name="Error" />

In ErrorPopup.xaml.cs add a private member and control its value through the property:

private string _errorMessage;
public string ErrorMessage
{
    get { return _errorMessage; }
    set
    {
        _errorMessage = value;
    }
}

Now add the following code to ensure every time the ErrorPopup is loaded it displays the error message that it received through its property (ErrorMessage):

private void ErrorPopup_Loaded(object sender, RoutedEventArgs e)
{
    Error.Text = _errorMessage;
}

3. Show ErrorPopup and pass an error message
in MainPage.xaml.cs create a private variable of type ErrorPopup:

private ErrorPopup errorPopup;

In Loaded or constructor method create a new instance of the errorPopup:

errorPopup = new ErrorPopup();

Now you are ready to use the ErrorPopup every time needed within your application. So in your MainFrame_NavigationFailed method add the following code:

errorPopup.ErrorMessage = "Page you were trying to access could not be found.";
errorPopup.Show();

don’t forget to keep e.Handled = true; in that method as otherwise you receive the exception error I explained above.

Please note in the download from CodePlex I included both methods and just commented the display through Error404 template out by commenting out the MainFrame.Navigate function in the MainFrame_NavigationFailed method. Feel free to put that line back in and comment the other method out if you needed to.

I personally prefer to you the ErrorPopup, but depending on your need you can user either of the two options I explained above.

Posted by Damon Serji on 4. December 2009 00:06 under: Intermediate
 with 2 Comments