— New online course!  Getting Started with Azure DevOps — Special launch price 50% off —

Bind a Silverlight 4 HyperlinkButton NavigateUri in a DataGrid to a DataSource value

by

The Problem: How to generate a NavigateUri for a HyperlinkButton in a DataGrid that contains an Id value using a data binding expression.
The Answer: Use StringFormat inside the NavigateUri binding.

It’s a pretty common thing to do in any kind of application – you’ve got a grid that’s filled with data and from that grid you need to display the detail for that record when a user clicks on the row.  In the image below, I’ve got a list of people and when you click on the “(view)” link, it takes you to the detail for that person.

image

image

A few days ago, I needed to implement this kind of functionality in Silverlight 4.  In my application, I’m using Silverlight Pages and Navigation Frames to move around throughout the application.  When I move to a new Page in the application, it usually is done via a HyperlinkButton control with the NavigateUri set to something like “/Views/About”

image

Using that Uri scheme, I’ve got a folder in my Silverlight project named Views and inside that folder, I’ve got a Silverlight Page named About.xaml.  Extending that uri naming scheme and making it look like a lot of the web an a lot of things that happen in ASP.NET MVC Framework, let’s say that I have a page called PersonDetail that allows the user to edit a specific Person record.  When I needed to navigate to a particular person, I wanted the Uri for that PersonDetail page to be something like “/Views/PersonDetail/6” where that last part of the uri – the ‘6’ – is the Id for the Person that I want to edit.

Since I was going to display these records in a DataGrid, I wanted to be able to use a data binding expression an a DataGridTemplateColumn that contains a HyperlinkButton and have the NavigateUri be generated automatically that would point to PersonDetail.  Sounds simple, right? Well, when I searched around on The Internet(s), it looked like it was going to be really hard.  Some posts suggested creating a custom version of the HyperlinkButton control, others suggested hooking in to the binding events on the DataGrid, and then there was also a suggestion that I write a value converter to plug in to the NavigatieUri binding expression.  It looked grim. 

Well, it looks like it’s gotten a lot easier in Silverlight 4. 

The answer: use StringFormat inside the NavigateUri binding.  (See the block of WPF Xaml below)

<sdk:DataGrid ItemsSource=”{Binding Persons}” AutoGenerateColumns=”False” >
    <sdk:DataGrid.Columns>
        <sdk:DataGridTemplateColumn CanUserReorder=”True” CanUserResize=”True” CanUserSort=”True” Width=”Auto”>
            <sdk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <HyperlinkButton Content=”(view)” Tag=”{Binding Id}”
                                 NavigateUri=”{Binding Id, StringFormat=’/PersonDetail/{0}’}”
                                 TargetName=”ContentFrame” VerticalAlignment=”Center”></HyperlinkButton>
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellTemplate>
        </sdk:DataGridTemplateColumn>
        <sdk:DataGridTextColumn CanUserReorder=”True” CanUserResize=”True” CanUserSort=”True” Width=”Auto” Header=”Id” Binding=”{Binding Id}”/>
        <sdk:DataGridTextColumn CanUserReorder=”True” CanUserResize=”True” CanUserSort=”True” Width=”Auto” Header=”Last Name” Binding=”{Binding LastName}”/>
        <sdk:DataGridTextColumn CanUserReorder=”True” CanUserResize=”True” CanUserSort=”True” Width=”Auto” Header=”First Name” Binding=”{Binding FirstName}”/>
    </sdk:DataGrid.Columns>
</sdk:DataGrid>

Click here to view a running sample application
Click here to download the source code for this example.

-Ben

— Looking for help with your Silverlight architecture?  Worried about getting it right the first time?  Questions about how to unit test your Silverlight application?  Drop us a line: info@benday.com


One Response to "Bind a Silverlight 4 HyperlinkButton NavigateUri in a DataGrid to a DataSource value"
  1. Hi Benjamin
    I think I am close to getting this working.
    I am trying to do this with a Frame within a Page.
    When I press the View it fires off with mynewPage/ID which in this example is a country.
    I get a 4004 error when I change the Target name to MyFrame.
    Any Help would be appreciated
    Thanks

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: