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.
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
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
Get Microsoft Silverlight

The built-in validation in Silverlight 3.0 is a great new feature that can be used on essential Silverlight controls such as TextBox. Using this feature, it is possible to nicely display an error message and highlight the TextBox that has bad value.

In this post I will only cover validating data in TextBox controls, which are simply used in most forms to receive basic information such as Name, Surname and Email address. The completed and working version of this project can be downloaded from CodePlex from here. I will explain and provide solution on how to validate ComboBox, Radio Button controls or etc in another post soon, so please keep yourself updated on new posts here.

1. Create a basic form with a few TextBox controls in the xaml

2. Create a class, call it CustomValidation
Add the following code to your CustomValidation class:

private string message;
public CustomValidation(string message)
{
    this.message = message;
}
public bool ShowErrorMessage
{
    get;
    set;
}
public object ValidationError
{
    get
    {
        return null;
    }
    set
    {
        if (ShowErrorMessage)
        {
            throw new ValidationException(message);
        }
    }
}

3. Create an Extension class (Extensions)
To understand what is an Extension class and for more information about them visit my tutorial post “Extension methods in Silverlight and C#”.

In brief: Extensions will be your Extension class to extend any object of type FrameworkElement like TextBox controls within your application framework. It means you can use the public methods within this class as a “built-in” method for your TextBox.

Create a static public method and call it SetValidation. This method receives an instance of a FrameWorkElement and a string value, and returns nothing:

public static void SetValidation(this FrameworkElement frameworkElement, string message)
{
    CustomValidation customValidation = new CustomValidation(message);
    Binding binding = new Binding("ValidationError")
    {
        Mode = System.Windows.Data.BindingMode.TwoWay,
        NotifyOnValidationError = true,
        ValidatesOnExceptions = true,
        Source = customValidation
    };
    frameworkElement.SetBinding(Control.TagProperty, binding);
}

CustomValidation is the class we defined earlier.

"Binding" is a class in System.Windows.Data assembly which gets or sets a value that indicates whether to raise the error attached event on the bound object.

What are we doing? Here we have a CustomValidation class that has one property ("ShowErrorMessage") and one public methods ("ValidationError"). "ValidationError" is our source binding object and what we want to be able to do in the future is to bind our frameworkElement, which is a TextBox, to ValidationError. We are in simple words binding the CustomValidation class to our TextBox once we call this method on our TextBox.

For more information on Binding and BindingExpression visi msdn article here.

Create another two methods for displaying validation error and also for clearing validation error when the error was corrected:

public static void RaiseValidationError(this FrameworkElement frameworkElement)
{
    BindingExpression b =
    frameworkElement.GetBindingExpression(Control.TagProperty);
    if (b != null)
    {
        ((CustomValidation)b.DataItem).ShowErrorMessage = true;
        b.UpdateSource();
    }
}

public static void ClearValidationError(this FrameworkElement frameworkElement)
{
    BindingExpression b =
    frameworkElement.GetBindingExpression(Control.TagProperty);
    if (b != null)
    {
        ((CustomValidation)b.DataItem).ShowErrorMessage = false;
        b.UpdateSource();
    }
}

By creating a new BindingExpression you will be creating an instance of your binding so you can control the properties and public methods of your binding source/target. In above case, we are casting the BindingExpression.DataItem as CustomValidation. This enables us to access the properties of this class, "ShowErrorMessage" in this case.

4. RaiseValidationError() and ClearValidationError()
So now we have our TextBox, a method in our Extension class to bind the TextBox to our CustomValidation class and passes our error message, and a method in our Extension class that fires throw new ValidationException(message); from the CustomValidation class.

All we need to do now is to check if a specific TextBox is valid or not. If the TextBox was not valid we can simply use the RaiseValidationError() and ClearValidationError() methods, which should now be available from the intellisense in Visual Studio, to throw the validation exception and display a suitable error message and we do that by following code when the submit button was pressed:

Name.ClearValidationError();
bool isFormValid = true;
if (Name.Text == "")
{
    Name.SetValidation("Please enter your name");
    Name.RaiseValidationError();
    isFormValid = false;
}

use isFormValid variable to check if you have to submit the form or not. The Name.ClearValidationError() makes sure you clear the form everytime you press submit, so if the form was valid the error message had already been cleaned.

I have some extra validation extensions on this project and have organised the code in different class files. Download the project from here.

Posted by Damon Serji on 8. October 2009 19:24 under: Advance, Intermediate
 with 9 Comments

DeepLinking is one of the greatest features of Silverlight 3 in my opinion and this post will show you how to add Deep Linking to your Silverlight application in four simple steps:

1. Add Frame control in MainPage.xaml
Add System.Windows.Controls.Navigation in your project References and then a reference to navigation namespace to enable you adding the Frame control.


<UserControl x:Class="SilverlightDeepLinking.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Nav="clr-namespace:System.Windows.Controls;
               assembly=System.Windows.Controls.Navigation"

    mc:Ignorable="d" d:DesignWidth="546" d:DesignHeight="150">
  <Grid Width="546" Height="150" x:Name="LayoutRoot" Background="#FFC2CBD8">
    <Nav:Frame x:Name="MainFrame" UriMapper="{StaticResource uriMapper}"
    HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
  </Grid>
</UserControl>

2. Add URI Routing using UriMapper


<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="SilverlightDeepLinking.App"
             xmlns:Nav="clr-namespace:System.Windows.Navigation;
             assembly=System.Windows.Controls.Navigation"
>
    <Application.Resources>
        <Nav:UriMapper x:Key="uriMapper">
            <Nav:UriMapping Uri="" MappedUri="/HomePage.xaml" />
            <Nav:UriMapping Uri="About" MappedUri="/About.xaml" />
        </Nav:UriMapper>
    </Application.Resources>
</Application>

3. Add your pages to the application
Here I have added a Homepage.xaml and About.xaml and added different content and color to them.

4. Add navigation links to your MainPage.xaml
Since we have Homepage and About page, I am going to add to HyperlinkButtons on my MainPage.xaml in order to enable me browse to my two different pages. Please note, the Homepage and About pages will appear inside your <Nav:Frame control, therefore we should have our navigation links i.e. on top/bottom and have the Frame in the middle, where the content will be displayed.

Here is the MainPage.xaml after adding the HyperlinkButtons and adjusting the layout:


<Grid Width="546" Height="150" x:Name="LayoutRoot" Background="#FFC2CBD8">
    <HyperlinkButton x:Name="HomeLink" Content="Homepage"
    HorizontalAlignment="Center" Margin="0,2,60,0" Height="15"
     VerticalAlignment="Top" Background="#009A480E"
     Foreground="#FFC55314" />
    <HyperlinkButton x:Name="AboutLink" Content="About"
     HorizontalAlignment="Center" Margin="60,2,0,0" Height="15"
     VerticalAlignment="Top" Foreground="#FFC55314" />
    <Nav:Frame x:Name="MainFrame" UriMapper="{StaticResource uriMapper}"
    HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
     Margin="0,20,0,0" />
</Grid>

Add the code behind MainPage.xaml.cs

public MainPage()
{
    InitializeComponent();
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    HomeLink.Click += new RoutedEventHandler(HomeLink_Click);
    AboutLink.Click += new RoutedEventHandler(AboutLink_Click);
}
private void AboutLink_Click(object sender, RoutedEventArgs e)
{
    MainFrame.Navigate(new Uri("About", UriKind.Relative));
}
private void HomeLink_Click(object sender, RoutedEventArgs e)
{
    MainFrame.Navigate(new Uri("", UriKind.Relative));
}

When you click on the About link, you will navigate away from the current page, note the "#About" at the end of the URL.

The complete project can be downloaded from here.

Posted by Damon Serji on 6. September 2009 12:48 under: Basic
 with 3 Comments