This article will show how to use resources in WPF.
There are two types of resources.
- Static Resources
- Dynamic Resources
Static Resources
- A Static Resource will be resolved and assigned to the property
during the loading of the XAML which occurs before the application is
actually run. It will only be assigned once and any changes to resource
dictionary ignored.
Static resource references work best for the following circumstances:
- Your
application design concentrates most of all of its resources into page
or application level resource dictionaries. Static resource references
are not re-evaluated based on runtime behaviours such as reloading a
page, and therefore there can be some performance benefit to avoiding
large numbers of dynamic resource references when they are not necessary
per your resource and application design.
- You are setting the value of a property that is not on a Dependency Object or a freezable.
- You
are creating a resource dictionary that will be compiled into a DLL,
and packaged as part of the application or shared between applications.
- You
are creating a theme for a custom control, and are defining resources
that are used within the themes. For this case, you typically do not
want the dynamic resource reference lookup behaviour; you instead want
the static resource reference behaviour so that the lookup is
predictable and self-contained to the theme. With a dynamic resource
reference, even a reference within a theme is left unevaluated until
runtime, and there is a chance that when the theme is applied, some
local element will redefine a key that your theme is trying to
reference, and the local element will fall prior to the theme itself in
the lookup. If that happens, your theme will not behave in an expected
manner.
- You are using resources to set large numbers of
dependency properties. Dependency properties have effective value
caching as enabled by the property system, so if you provide a value for
a dependency property that can be evaluated at load time, the
dependency property does not have to check for a re-evaluated expression
and can return the last effective value. This technique can be a
performance benefit.
- You want to change the underlying resource
for all consumers, or you want to maintain separate writable instances
for each consumer by using the x: Shared Attribute.
Example:
<Window.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
<Style
TargetType="Border" x:Key="PageBackground">
<Setter
Property="Background" Value="black"/>
</Style>
<Style
TargetType="TextBlock" x:Key="TitleText">
<Setter
Property="Background" Value="Green"/>
<Setter
Property="DockPanel.Dock" Value="Top"/>
<Setter
Property="FontSize" Value="14"/>
<Setter
Property="Foreground" Value="#4E87D4"/>
<Setter
Property="FontFamily" Value="Tahoma"/>
<Setter
Property="Margin" Value="0,40,10,10"/>
<Setter
Property="Width" Value="300"></Setter>
</Style>
<Style
TargetType="TextBlock" x:Key="Label">
<Setter
Property="DockPanel.Dock" Value="Right"/>
<Setter
Property="FontSize" Value="8"/>
<Setter
Property="Foreground" Value="{StaticResource MyBrush}"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter
Property="FontWeight" Value="Bold"/>
<Setter
Property="Margin" Value="0,3,10,0"/>
<Setter
Property="Width" Value="100"></Setter>
<Setter
Property="Height" Value="20"></Setter>
</Style>
</Window.Resources>
This is how we use resource in controls
<Grid>
<StackPanel>
<Border
Style="{StaticResource PageBackground}">
<DockPanel>
<TextBlock
Style="{StaticResource TitleText}">Welcome to the static resource
page</TextBlock>
<TextBlock
Style="{StaticResource Label}">This is label text</TextBlock>
<TextBlock
DockPanel.Dock="Top" HorizontalAlignment="Left" FontSize="20" Foreground="{StaticResource MyBrush}"
Text="Hello Rajkumar Welcome !" Margin="20" />
<Button
DockPanel.Dock="Top" HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}"
Margin="40">Click To Enter :)</Button>
<Ellipse
DockPanel.Dock="Top" HorizontalAlignment="Left" Width="100" Height="100" Fill="{StaticResource MyBrush}" />
</DockPanel>
</Border>
</StackPanel>
</Grid>
Run application and see the result like this:
Image 1.
Dynamic Resources
- A Dynamic Resource assigns an Expression object to the property
during loading but does not actually lookup the resource until runtime
when the Expression object is asked for the value. This defers looking
up the resource until it is needed at runtime. A good example would be a
forward reference to a resource defined later on in the XAML. Another
example is a resource that will not even exist until runtime. It will
update the target if the source resource dictionary is changed.
Dynamic resources work best for the following circumstances:
- The
value of the resource depends on conditions that are not known until
runtime. This includes system resources, or resources that are otherwise
user settable. For example, you can create setter values that refer to
system properties, as exposed by System Colours, System Fonts, or System
Parameters. These values are truly dynamic because they ultimately come
from the runtime environment of the user and operating system. You
might also have application-level themes that can change, where
page-level resource access must also capture the change.
- You are creating or referencing theme styles for a custom control.
- You intend to adjust the contents of a Resource Dictionary during an application lifetime.
- You
have a complicated resource structure that has interdependencies, where
a forward reference may be required. Static resource references do not
support forward references, but dynamic resource references do support
them because the resource does not need to be evaluated until runtime,
and forward references are therefore not a relevant concept.
- You
are referencing a resource that is particularly large from the
perspective of a compile or working set, and the resource might not be
used immediately when the page loads. Static resource references always
load from XAML when the page loads; however, a dynamic resource
reference does not load until it is actually used.
- You are creating a style where setter values might come from other values that are influenced by themes or other user settings.
- You
are applying resources to elements that might be represented in the
logical tree during application lifetime. Changing the parent also
potentially changes the resource lookup scope, so if you want the
resource for a represented element to be revaluated based on the new
scope; always use a dynamic resource reference.
Example:
<Window.Resources>
<SolidColorBrush x:Key="brush" Color="Green" />
<Style
TargetType="Border" x:Key="PageBackground">
<Setter
Property="Background" Value="Gold"/>
</Style>
</Window.Resources>
<Grid>
<Border
Style="{DynamicResource PageBackground}">
<Button x:Name="btn" Content="Rajkumar Test" Click="Button_Click" Background="{DynamicResource brush}"
Height="30" Margin="53,130,85,130" />
</Border>
</Grid>
You can apply on code behind like this.
private void Button_Click(object
sender, RoutedEventArgs e)
{
this.btn.SetResourceReference(BackgroundProperty, "brush");
}
Output will be like this.