As you have already seen, each UI element that we use in our Views takes time to render. Simply put, the fewer elements that we use, the quicker the View will be displayed. Those of us that have used Hyperlink elements in our Views will already be aware that we cannot display them on their own but, instead, have to wrap them inside a TextBlock element.
However, as each Hyperlink element is self-contained, with its own navigation URI, content, and property options, we can actually display more than one of them in a single TextBlock element. This will reduce the render time; therefore, the more TextBlock elements that we can remove, the quicker it will become. Let's look at an example:
<ListBox ItemsSource="{Binding Products}" FontSize="14" HorizontalContentAlignment="Stretch"> <ListBox.ItemTemplate> <DataTemplate DataType="{x:Type DataModels:Product}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Name}" /> <TextBlock Grid.Column="1" Text="{Binding Price, StringFormat=C}" Margin="10,0" /> <StackPanel Grid.Column="2" TextElement.FontSize="14" Orientation="Horizontal"> <TextBlock> <Hyperlink Command="{Binding ViewCommand, RelativeSource={RelativeSource AncestorType={x:Type Views:TextView}}}" CommandParameter="{Binding}">View</Hyperlink> </TextBlock> <TextBlock Text=" | " /> <TextBlock> <Hyperlink Command="{Binding EditCommand, RelativeSource={RelativeSource AncestorType={x:Type Views:TextView}}}" CommandParameter="{Binding}">Edit</Hyperlink> </TextBlock> <TextBlock Text=" | " /> <TextBlock> <Hyperlink Command="{Binding DeleteCommand, RelativeSource={RelativeSource AncestorType={x:Type Views:TextView}}}" CommandParameter="{Binding}">Delete</Hyperlink> </TextBlock> </StackPanel> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Here, we have a collection of Product objects that are data bound to a ListBox, with each item displaying its name, price, and three commands in the form of Hyperlink objects. Let's see what this looks like before continuing:

Focusing on the links now, our example uses nine UI elements per item to render these three links. The StackPanel element keeps them altogether, with each Hyperlink object having its own TextBlock element and a further two TextBlock elements to display the pipe separator characters.
The Hyperlink objects are data bound to commands in the View Model and the CommandParameter property is data bound to the whole Product object that is set as the data source for each item. In this way, we will have access to the relevant Product instance in the View Model when a link is clicked on.
While there is nothing wrong with this XAML, if we need to be more efficient, then we can replace everything inside the StackPanel and the panel itself with the following TextBlock element:
<TextBlock Grid.Column="2" TextElement.FontSize="14" Foreground="White"> <Hyperlink Command="{Binding ViewCommand, RelativeSource={ RelativeSource AncestorType={x:Type Views:TextView}}}" CommandParameter="{Binding}">View</Hyperlink> <Run Text=" | " /> <Hyperlink Command="{Binding EditCommand, RelativeSource={ RelativeSource AncestorType={x:Type Views:TextView}}}" CommandParameter="{Binding}">Edit</Hyperlink> <Run Text=" | " /> <Hyperlink Command="{Binding DeleteCommand, RelativeSource={ RelativeSource AncestorType={x:Type Views:TextView}}}" CommandParameter="{Binding}">Delete</Hyperlink> </TextBlock>
As you can see, we now host all three Hyperlink objects inside a single TextBlock element and have replaced the two TextBlock elements that displayed the pipe characters with Run objects. Using the Run class is moderately more efficient than using one TextBlock element inside another.
Now, we need only render six elements per item to produce the links, including using two more efficient elements, rendering three elements fewer per item. However, if we had 1,000 products, we would end up rendering 3,000 fewer UI elements, with 2,000 more efficient replacements, so it is easy to see how this can soon add up to some real efficiency savings.
In this example, we could make further improvements, simply by removing the line under each link. Bizarrely, we can save up to 25 percent of the rendering time taken to render our Hyperlink elements if we remove their underlines. We can do this by setting their TextDecorations property to None:
<Hyperlink ... TextDecorations="None">View</Hyperlink>
We could extend this idea further, by only displaying the underline when the user's mouse cursor is over the link. In this way, we still give the visual confirmation that the link is, in fact, a link, but we save the initial rendering time:
<Style TargetType="{x:Type Hyperlink}">
<Setter Property="TextDecorations" Value="None" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="TextDecorations" Value="Underline" />
</Trigger>
</Style.Triggers>
</Style>
Let's now turn our attention to a number of performance improvements that we can make when data binding in our applications.