One of the strength points for WPF is the ability to set a property value using a wide range of methods.
Unfortunately, this variety makes it hard to understand how a WPF dependency property gets its final value. Hopefully this post will help organize this issue.
This post is based on the comprehensive MSDN article “Dependency Property Value Precedence”.
Long Story Short
Can you show an example please?
In order to see this in action let’s create a WPF application that has all these scenarios used.
For this to be possible we will create a custom control named MyCustomControl and add it a dependency property named MyValue which we’ll use for setting values from different places.
To see the actual value at runtime we will present this property in a TextBlock. In fact, our custom control will have just that in his control template.
Step 1 – Default Value
First we add our dependency property and set its default value to “1”.
public string MyValue
{
get { return (string)GetValue(MyValueProperty); }
set { SetValue(MyValueProperty, value); }
}
public static readonly DependencyProperty MyValueProperty =
DependencyProperty.Register("MyValue", typeof(string), typeof(MyCustomControl), new UIPropertyMetadata("1"));
After setting the default control template (Themes\Generic.xaml) as follows:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo">
<Style TargetType="{x:Type local:MyCustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyCustomControl}">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="32"
Text="{TemplateBinding MyValue}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
And the main window to:
<Window x:Class="DependencyPropertyValueResolutionDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo"
Title="MainWindow" Height="150" Width="150">
<Grid>
<local:MyCustomControl />
</Grid>
</Window>
We get:

Step 2 – Inheritance
To support inheritance we will change our dependency property into an attached property that can also be set using CLR property syntax.
In addition we will add FrameworkPropertyMetadataOptions.Inherits option to the property registration to allow the value to be inherited.
So the property declaration now goes:
public static string GetMyValue(DependencyObject obj)
{
return (string)obj.GetValue(MyValueProperty);
}
public static void SetMyValue(DependencyObject obj, string value)
{
obj.SetValue(MyValueProperty, value);
}
public static readonly DependencyProperty MyValueProperty =
DependencyProperty.RegisterAttached("MyValue", typeof(string), typeof(MyCustomControl),
new FrameworkPropertyMetadata("1", FrameworkPropertyMetadataOptions.Inherits));
public string MyValue
{
get { return GetMyValue(this); }
set { SetMyValue(this, value); }
}
And its use in the main window:
<Window x:Class="DependencyPropertyValueResolutionDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo"
Title="MainWindow" Height="150" Width="150">
<Grid local:MyCustomControl.MyValue="2">
<local:MyCustomControl />
</Grid>
</Window>
Which results in:

Step 3 - Default (theme) style
Adding a setter to the default style overrides the previous definition:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo">
<Style TargetType="{x:Type local:MyCustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyCustomControl}">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="32"
Text="{TemplateBinding MyValue}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="MyValue" Value="3" />
</Style>
</ResourceDictionary>
So now we get:

Step 4 - Style setters
We can override the previous value by setting a style setter in the main window:
<Window x:Class="DependencyPropertyValueResolutionDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo"
Title="MainWindow" Height="150" Width="150">
<Grid local:MyCustomControl.MyValue="2">
<local:MyCustomControl>
<local:MyCustomControl.Style>
<Style TargetType="local:MyCustomControl">
<Setter Property="MyValue" Value="4" />
</Style>
</local:MyCustomControl.Style>
</local:MyCustomControl>
</Grid>
</Window>
So now we get:

Step 5 - Template triggers
Now we will override our default template and add a template trigger, which will act when IsEnabled = True (I’ve just selected the property arbitrarily).
<Window x:Class="DependencyPropertyValueResolutionDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo"
Title="MainWindow" Height="150" Width="150">
<Grid local:MyCustomControl.MyValue="2">
<local:MyCustomControl>
<local:MyCustomControl.Style>
<Style TargetType="local:MyCustomControl">
<Setter Property="MyValue" Value="4" />
</Style>
</local:MyCustomControl.Style>
<local:MyCustomControl.Template>
<ControlTemplate TargetType="local:MyCustomControl">
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="MyValue" Value="5" />
</Trigger>
</ControlTemplate.Triggers>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="32"
Text="{TemplateBinding MyValue}" />
</ControlTemplate>
</local:MyCustomControl.Template>
</local:MyCustomControl>
</Grid>
</Window>
The result:

Step 6 - Style triggers
Now we add a trigger to the explicit style we’ve added before:
<Window x:Class="DependencyPropertyValueResolutionDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo"
Title="MainWindow" Height="150" Width="150">
<Grid local:MyCustomControl.MyValue="2">
<local:MyCustomControl>
<local:MyCustomControl.Style>
<Style TargetType="local:MyCustomControl">
<Setter Property="MyValue" Value="4" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="MyValue" Value="6" />
</Trigger>
</Style.Triggers>
</Style>
</local:MyCustomControl.Style>
<local:MyCustomControl.Template>
<ControlTemplate TargetType="local:MyCustomControl">
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="MyValue" Value="5" />
</Trigger>
</ControlTemplate.Triggers>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="32"
Text="{TemplateBinding MyValue}" />
</ControlTemplate>
</local:MyCustomControl.Template>
</local:MyCustomControl>
</Grid>
</Window>
The result:

Step 7 - Implicit style
This step is brought here for completeness although we can’t use it to override the value of MyValue dependency property.
It is relevant ONLY if the dependency property you are trying to set is the Style property.
Step 8 - TemplatedParent template properties
OK, this is a tough one.
Here we set the value “8” (I skipped “7” to remain consistent with the step number) by setting the MyValue property on a MyCustomControl instance, BUT, only when it is generated as a template (by setting either a ControlTemplate or DataTemplate).
In the following code I’m creating a ContentControl, only to set its control template (via the Template property) to an instance of MyCustomControl. On this instance of MyCustomControl I set MyValue property to 8.
This appears to be setting a local value but it really isn’t!
The reason is that this template can be shared across several controls. So the value is saved behind the scenes as part of the template properties. We will see in the next step that setting a true local value will override this. In the mean time here is the code:
<Window x:Class="DependencyPropertyValueResolutionDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo"
Title="MainWindow" Height="150" Width="150">
<Grid local:MyCustomControl.MyValue="2">
<ContentControl x:Name="contentControl">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<local:MyCustomControl MyValue="8" x:Name="myCustomControl">
<local:MyCustomControl.Style>
<Style TargetType="local:MyCustomControl">
<Setter Property="MyValue" Value="4" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="MyValue" Value="6" />
</Trigger>
</Style.Triggers>
</Style>
</local:MyCustomControl.Style>
<local:MyCustomControl.Template>
<ControlTemplate TargetType="local:MyCustomControl">
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="MyValue" Value="5" />
</Trigger>
</ControlTemplate.Triggers>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="32"
Text="{TemplateBinding MyValue}" />
</ControlTemplate>
</local:MyCustomControl.Template>
</local:MyCustomControl>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</Grid>
</Window>
And the result:

Step 9 - Local value
In this step I’ll show you how I can override the previous template value by setting a local value from a button click handler. To prove that I’m not setting the same thing as in step 8 I’ll add another button that will clear the value, in which case the older value (“8”) will be restored.
So following is the code for main window, I’ve only added two buttons and replaced the main Grid with a StackPanel:
<Window x:Class="DependencyPropertyValueResolutionDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DependencyPropertyValueResolutionDemo"
Title="MainWindow" Height="150" Width="150">
<StackPanel local:MyCustomControl.MyValue="2">
<ContentControl x:Name="contentControl">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<local:MyCustomControl MyValue="8" x:Name="myCustomControl">
<local:MyCustomControl.Style>
<Style TargetType="local:MyCustomControl">
<Setter Property="MyValue" Value="4" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="MyValue" Value="6" />
</Trigger>
</Style.Triggers>
</Style>
</local:MyCustomControl.Style>
<local:MyCustomControl.Template>
<ControlTemplate TargetType="local:MyCustomControl">
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="MyValue" Value="5" />
</Trigger>
</ControlTemplate.Triggers>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="32"
Text="{TemplateBinding MyValue}" />
</ControlTemplate>
</local:MyCustomControl.Template>
</local:MyCustomControl>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
<Button Content="set local value" Click="Set_Local_Click" />
<Button Content="clear local value" Click="Clear_Local_Click" />
</StackPanel>
</Window>
Following is the implementation of the buttons. In order to find the generated MyCustomControl I use the method FrameworkTemplate.FindName.
Note that I don’t set the value “8” in the code, instead I use ClearValue and it’s gets restored since the value is saved inside the template definition.
private void Set_Local_Click(object sender, RoutedEventArgs e)
{
MyCustomControl myCustomControl = (MyCustomControl)contentControl.Template.FindName("myCustomControl", contentControl);
myCustomControl.MyValue = "9";
}
private void Clear_Local_Click(object sender, RoutedEventArgs e)
{
MyCustomControl myCustomControl = (MyCustomControl)contentControl.Template.FindName("myCustomControl", contentControl);
myCustomControl.ClearValue(MyCustomControl.MyValueProperty);
}
The result now, after clicking on “set local value” looks like this:

Step 10- Animation
OK, this one is easy.
To set a value using animation we’ll add a storyboard to the window resources:
<Window.Resources>
<Storyboard x:Key="animateValue">
<StringAnimationUsingKeyFrames Storyboard.TargetProperty="MyValue">
<DiscreteStringKeyFrame KeyTime="0:0:1" Value="10" />
</StringAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
And when the “animate value” button is clicked we will start the animation:
private void Animate_Click(object sender, RoutedEventArgs e)
{
MyCustomControl myCustomControl = (MyCustomControl)contentControl.Template.FindName("myCustomControl", contentControl);
Storyboard animateValue = (Storyboard)FindResource("animateValue");
animateValue.Begin(myCustomControl);
}
The result:

Step 11 - Property coercion
The last option for changing a dependency property value, which has the highest precedence is to use value coercion.
To use value coercion we just add a value coercion callback when registering the dependency property:
public static readonly DependencyProperty MyValueProperty =
DependencyProperty.RegisterAttached("MyValue", typeof(string), typeof(MyCustomControl),
new FrameworkPropertyMetadata("1", FrameworkPropertyMetadataOptions.Inherits, MyValueChanged, MyValueCoerceValue));
private static void MyValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
private static object MyValueCoerceValue(DependencyObject d, object baseValue)
{
return "11";
}
And the last result:

Now nothing can change our dependency property value!
Summary
We have seen 11 ways to affect a dependency property value, each time overriding the previous value. Hopefully you have learned something new about dependency property value resolution.
You can download the full source code for this demo here.
That’s it for now,
Arik Poznanski.
A few months ago I delivered a session on Windows 7 features in WPF and WinForms applications.

In this session I show, among other things, how to work with the Windows 7 Taskbar, how to work with sensors information (light, temperature, etc.), how to use the Windows 7 Ribbon and more.
Fortunately for all those who missed it, the session was recorded and is now available via Sela’s latest invention: Sela College Channel, a broadcasting channel for software related videos.

You can see the session on this link. Note that the session is in Hebrew.
Enjoy :)
That’s it for now,
Arik Poznanski.
My associate, Bernhard Elbl, as published another two posts on his blog further explaining the latest improvements in the Ribbon for WinForms project.
In the first post Bernhard explains what is the RibbonGenerator and how it is generating the .ribbon files.
In the second post he explains what does it takes to use the Ribbon for WinForms project using Visual Studio 2010 Express edition.
I suggest everyone who use this project to check out these posts.
Finally, I would like to thank Bernhard for his good work.
That’s it for now,
Arik Poznanski.
This post provides the technical details on how I’ve implemented the Windows Live Writer Plug-in Check For Missing Tags, which was presented here.
What Is This Plug-in Anyway?
This plug-in will remind you to add the proper tags if they are missing.
Trying to post without proper tagging when the plug-in is installed will result with the following dialog:
![image_thumb[2] image_thumb[2]](http://blogs.microsoft.co.il/blogs/arik/image_thumb2_thumb_203AFE36.png)
Clicking on the Cancel button (which is the default) will abort the publish operation and will let you update the categories.
The list of required categories is saved in a simple text file (required_categories.txt) next to the plug-in dll.
How It Was Built?
Following are the full instruction on how to build such a plug-in.
You can find the full source here.
- Create new class library project named CheckMissingTagsPlugin. Make sure you use .NET framework 3.5 since .NET 4 plugins are not supported.
- Add reference to WindowsLive.Writer.Api, located in C:\Program Files\Windows Live\Writer.
- Add reference to System.Windows.Forms, located in the GAC.
- Create a class named CheckMissingTags that inherits from PublishNotificationHook.
- Apply attribute WriterPluginAttribute to the class.
[WriterPlugin("EF0CAF97-12C2-4446-BDC4-19EE53781351", "Check For Missing Tags")]
public class CheckMissingTags : PublishNotificationHook
{
}
- Override the method OnPrePublish. Here we can check for missing categories and notify the user.
public override bool OnPrePublish(IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish)
{
// get list of required categories
string[] requiredCategories;
if (File.Exists(FileName))
{
requiredCategories = File.ReadAllLines(FileName);
}
else
{
// warn about missing required categories
string message =
"Missing categories file: " + FileName + "\n" +
"Post anyway?";
DialogResult dialogResult = MessageBox.Show(
dialogOwner,
message,
"Warning",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2);
// allow post only if user selected OK
return dialogResult == DialogResult.OK;
}
// get list of available categories
IEnumerable<string> availableCategories =
from category in publishingContext.PostInfo.Categories
select category.Name;
// is one of the required categories available?
bool hasAnyRequestedCategory = availableCategories.Any(
s => requiredCategories.Contains(s, StringComparer.OrdinalIgnoreCase));
if (!hasAnyRequestedCategory)
{
string allRequiredCategories = string.Join(", ", requiredCategories);
string message =
"None of the required categories are available.\n" +
"(" + allRequiredCategories + ")\n" +
"Post without required categories?";
// warn about missing required categories
DialogResult dialogResult = MessageBox.Show(
dialogOwner,
message,
"Warning",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2);
// allow post only if user selected OK
return dialogResult == DialogResult.OK;
}
return true;
}
- Add the following line to the post build event:
XCOPY /D /Y /R "$(TargetPath)" "%ProgramFiles%\Windows Live\Writer\Plugins\"
- Build project.
Note: In order for the post build event to work you need to run Visual Studio as Administrator.
That’s it for now,
Arik Poznanski.
Background
A few days ago, there was a bloggers meeting at Microsoft Raanana Office.
While I was there I’ve heard some people complain that they sometimes forget to add the proper tags to their blog posts (e.g. DEV, ITPRO, TECH, OFFTOPIC, VIDEO).
Presenting: Check For Missing Tags Plug-in
I’ve decided to pick up the glove and implement a Windows Live Writer plug-in that will remind you to add the proper tags.
Trying to post without proper tagging when the plug-in is installed will result with the following dialog:

Clicking on the Cancel button (which is the default) will abort the publish operation and will let you update the categories.
The list of required categories is saved in a simple text file (required_categories.txt) next to the plug-in dll.
How Do I Install This Cool Plug-in?
- Download the following zip file.
- Extract it into C:\Program Files\Windows Live\Writer\Plugins\ or the equivalent folder on your system (on 64 bit systems it’s Program Files (x86) ).
- Enjoy :)
If you’re interested in the code, check out the following post.
That’s it for now,
Arik Poznanski.
The other day I was teaching a WPF course when one of the students asked me where is the “Line” shape in the Visual Studio Toolbox.
I approach to show him, only to find out that this control is indeed missing from the Visual Studio 2010 Toolbox. Even if you search the alleged “All WPF Controls” tab..

After a quick check I’ve found that this is not the only shape missing. The missing shapes are: Line, Path, Polygon, Polyline. And who knows which other controls are missing.
Anyway, you can add this controls manually to the toolbox by following these steps:
- Right-click the toolbox tab where you want to add a control (e.g. “All WPF Controls” and select “Choose Items”.
- From the WPF Components tab choose the requested control (e.g. Line). You can use the Filter to help you find the control.

- And there you go. Now you have the missing control where you want it.

Note that it has a proper icon meaning the WPF team prepared this element to be on the toolbox, but somehow it slipped away.
That’s it for now,
Arik Poznanski.