WPF and Dependency property default objects

WPF is a completely new stuff respect to winform, and sometimes you can get surprised by its behaviour. Today I had a bug in a simple application, it seems that closing and opening a form, data is persisted between instances, and it seems that a dependency property is behaving like static variable. This is the situation exposed in simple way, take a parameter filter object like this

1
2
3
4
5
public class Filters
{
public String Name { get; set; }
public String Surname { get; set; }
}

Simple class with two properties, then create a wpf windows with this simple code behind.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public partial class FilterPage : Window
{
public FilterPage()
{
InitializeComponent();
}
 
public Filters Filters
{
get { return (Filters)GetValue(FiltersProperty); }
set { SetValue(FiltersProperty, value); }
}
 
// Using a DependencyProperty as the backing store for Filters.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty FiltersProperty =
DependencyProperty.Register(
"Filters",
typeof(Filters),
typeof(MainWindow),
new UIPropertyMetadata(new Filters()));
}

In the real situation we have a MVVM pattern where the MV descend from ContentElement and can declare dependency properties. The XAML of the windows is this one.

1
2
3
4
5
6
7
8
9
<Window x:Class="testWPF.FilterPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FilterPage" Height="300" Width="300" x:Name="this">
<StackPanel>
<TextBox Text="{Binding ElementName=this,Path=Filters.Name}"/>
<TextBox Text="{Binding ElementName=this,Path=Filters.Surname}"/>
</StackPanel>
</Window>

Where you have two textbox simply binding to the dependency property, now create a windows, type something inside one of the textbox, then close it,then reopen it and you will find that the original value is still there. It seems that the value stored in the dependency property is static, and this is really true because you are using the default value of the property.

A DependencyProperty is made by a static definition and a run time behavior that permits to set and get it from an object, but do not forget that the declaration of the DP is static and this means that the default value you pass with the UIPropertyMetadata object is static too. This means that the default value of a DP is shared between all instances of the object that uses it and the above code is wrong because the form is using the default value of the DP to bind to textbox. To make this work as you can expect, you need to assign a valid Filters object in the constructor of the windows avoiding to use the shared default instance.

1
2
3
4
5
public FilterPage()
{
Filters = new Filters();
InitializeComponent();
}

Now everything works as expected.

Alk.