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.
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”.
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
Leave a Reply