While prepping for some session I have to present, I started revisiting WPF 4 and taking a deeper look at what's new! One of the new markup extensions I noticed is the {x:Reference …}
markup extension!
“References an instance that is declared elsewhere in XAML markup. The reference refers to an element's x:Name
.”
So, where is this used! One of the first scenarios that comes to mind is the focus target… In WPF 3.0/3.5, If I wanted to associate keyboard shortcut with setting focus on a TextBox
, I needed to write the following code.
WPF 3.0/3.5
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="_Name:" Target="{Binding ElementName=nameTextBox}"
Grid.Row="0" Grid.Column="0" />
<TextBox x:Name="nameTextBox"
Grid.Row="0" Grid.Column="1" Width="200" />
<Label Content="_Surname:" Target="{Binding ElementName=surnameTextBox}"
Grid.Row="1" Grid.Column="0" />
<TextBox x:Name="surnameTextBox"
Grid.Row="1" Grid.Column="1" Width="200" />
</Grid>
</Window>
With WPF 4.0, this has become way easier… check this out.
WPF 4.0
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="_Name:" Target="{x:Reference nameTextBox}"
Grid.Row="0" Grid.Column="0" />
<TextBox x:Name="nameTextBox"
Grid.Row="0" Grid.Column="1" Width="200" />
<Label Content="_Surname:" Target="{x:Reference surnameTextBox}"
Grid.Row="1" Grid.Column="0" />
<TextBox x:Name="surnameTextBox"
Grid.Row="1" Grid.Column="1" Width="200" />
</Grid>
</Window>
And if the property you are binding to is marked with System.Windows.Markup.NameReferenceConverter
:
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="_Name:" Target="nameTextBox"
Grid.Row="0" Grid.Column="0" />
<TextBox x:Name="nameTextBox"
Grid.Row="0" Grid.Column="1" Width="200" />
<Label Content="_Surname:" Target="surnameTextBox"
Grid.Row="1" Grid.Column="0" />
<TextBox x:Name="surnameTextBox"
Grid.Row="1" Grid.Column="1" Width="200" />
</Grid>
</Window>
[NOTE] If you try this in WPF 3.5, you will get a “'UIElement' type does not have a public TypeConverter class.
” exception message.
Simple, isn’t it?
CodeProject