Introducing Resources in WPF and XAML
< Continued from page 2
Microsoft's documentation states that "You can define resources on any element." For example, you could also code a resource for the Grid like this:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</Grid.Resources>
<TextBlock Width="80" Height="30"
Name="Button1"
Style="{StaticResource myAlign}">
MyButton
</TextBlock>
</Grid>
</Window>
In fact, WPF defines a hierarchy of precedence in defining resources. Consider the following code:
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</Application.Resources>
</Application>
... and ...
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</Grid.Resources>
<TextBlock Width="80" Height="30"
Name="TextBlock1"
Style="{DynamicResource myAlign}">
<TextBlock.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</TextBlock.Resources>
Content
</TextBlock>
</Grid>
</Window>
Notice that the Style element is defined three times with a myAlign key:
The version above results in the TextBlock being centered because the XAML loader processes the element first. Remove the TextBlock element resource by commenting it out:
<<!--
TextBlock.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</TextBlock.Resources>
-->
The Grid resource definition is next and the TextBlock element becomes left aligned. Comment that out and the TextBlock element becomes right aligned. Just like CSS! But notice that I switched to DynamicResources in the TextBlock instead of StaticResources. That switch was necessary because StaticResources are defined by the XAML loader in the sequence that they are encountered in the code. Because the Style attribute came first, it would get the next item in the precedence sequence right then instead of waiting to find the <TextBlock.Resources> block just a few lines down. That would result in a Left Value from <Grid.Resources>. Try it and see.
This just scratches the surface of what both resources and markup extensions can do. Check out the WPF tutorial to see a more complex example.
Microsoft's documentation states that "You can define resources on any element." For example, you could also code a resource for the Grid like this:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</Grid.Resources>
<TextBlock Width="80" Height="30"
Name="Button1"
Style="{StaticResource myAlign}">
MyButton
</TextBlock>
</Grid>
</Window>
In fact, WPF defines a hierarchy of precedence in defining resources. Consider the following code:
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</Application.Resources>
</Application>
... and ...
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</Grid.Resources>
<TextBlock Width="80" Height="30"
Name="TextBlock1"
Style="{DynamicResource myAlign}">
<TextBlock.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</TextBlock.Resources>
Content
</TextBlock>
</Grid>
</Window>
Notice that the Style element is defined three times with a myAlign key:
- TextBlock.Resources
- Grid.Resources
- Application.Resources
The version above results in the TextBlock being centered because the XAML loader processes the element first. Remove the TextBlock element resource by commenting it out:
<<!--
TextBlock.Resources>
<Style x:Key="myAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</TextBlock.Resources>
-->
The Grid resource definition is next and the TextBlock element becomes left aligned. Comment that out and the TextBlock element becomes right aligned. Just like CSS! But notice that I switched to DynamicResources in the TextBlock instead of StaticResources. That switch was necessary because StaticResources are defined by the XAML loader in the sequence that they are encountered in the code. Because the Style attribute came first, it would get the next item in the precedence sequence right then instead of waiting to find the <TextBlock.Resources> block just a few lines down. That would result in a Left Value from <Grid.Resources>. Try it and see.
This just scratches the surface of what both resources and markup extensions can do. Check out the WPF tutorial to see a more complex example.
Source...