Reputation: 13
When I define a collection of objects that each contain a collection like this:
<Graph2:NestedObjectTest x:Key="nestedTest">
<Graph2:NestedObjectTest.Children>
<Graph2:ChildNestedObjectTest>
<Graph2:ChildNestedObjectTest.Children>
<Point X="0" Y="0"/>
<Point X="10" Y="10"/>
<Point X="20" Y="20"/>
</Graph2:ChildNestedObjectTest.Children>
</Graph2:ChildNestedObjectTest>
<Graph2:ChildNestedObjectTest>
<Graph2:ChildNestedObjectTest.Children>
<Point X="1" Y="0"/>
<Point X="11" Y="10"/>
<Point X="21" Y="20"/>
</Graph2:ChildNestedObjectTest.Children>
</Graph2:ChildNestedObjectTest>
<Graph2:ChildNestedObjectTest>
<Graph2:ChildNestedObjectTest.Children>
<Point X="2" Y="0"/>
<Point X="12" Y="10"/>
<Point X="22" Y="20"/>
</Graph2:ChildNestedObjectTest.Children>
</Graph2:ChildNestedObjectTest>
</Graph2:NestedObjectTest.Children>
</Graph2:NestedObjectTest>
Each of the ChildNestedObjectTest objects gets all nine of the Point objects, instead of each getting the three objects that it appears they should have. Why is this?
The code behind is:
namespace Graph2
{
public class NestedObjectTest : DependencyObject
{
public static readonly DependencyProperty ChildrenProperty = DependencyProperty.Register("Children", typeof(List<ChildNestedObjectTest>), typeof(NestedObjectTest), new FrameworkPropertyMetadata(new List<ChildNestedObjectTest>()));
public List<ChildNestedObjectTest> Children
{
get { return (List<ChildNestedObjectTest>)GetValue(ChildrenProperty); }
set { SetValue(ChildrenProperty, value); }
}
}
public class ChildNestedObjectTest : DependencyObject
{
public static readonly DependencyProperty ChildrenProperty = DependencyProperty.Register("Children", typeof(List<Point>), typeof(ChildNestedObjectTest), new FrameworkPropertyMetadata(new List<Point>()));
public List<Point> Children
{
get { return (List<Point>)GetValue(ChildrenProperty); }
set { SetValue(ChildrenProperty, value); }
}
}
}
And I tested by adding the xaml to a window as a resource, then using:
Graph2.NestedObjectTest test = (Graph2.NestedObjectTest)this.Resources["nestedTest"];
Upvotes: 1
Views: 44
Reputation: 13898
Collection-Type Dependency Properties
If your property is a reference type, the default value specified in dependency property metadata is not a default value per instance; instead it is a default value that applies to all instances of the type.
Looks like the default static value you set in the metadata
new FrameworkPropertyMetadata(new List<Point>(),
^
---- This
Is resused whenever, the closed generic is another DependencyObject / Freezable
To correct this problem, you must reset the collection dependency property value to a unique instance, as part of the class constructor call. Because the property is a read-only dependency property, you use the SetValue(DependencyPropertyKey, Object) method to set it, using the DependencyPropertyKey that is only accessible within the class.
public NestedObjectTest() : base()
{
SetValue(ChildrenProperty, new List<ChildNestedObjectTest>());
}
and
public ChildNestedObjectTest() : base()
{
SetValue(ChildrenProperty, new List<Point>());
}
Upvotes: 2