Be careful with Default-Values of Dependency-Properties if you’re using Reference-Types.
I’ve justed finished a small PieMenu for a WPF-Application for one of our customers in switzerland. The PieMenu is displayed below with a black-red-style. The Style, colors and items can be changed individually. The colors and icons etc. in the PieMenu below are just the ones I’ve created for testing purposes.
While developing this PieMenu I’ve implemented several Dependency-Properties. Some of them containing ObservableCollections as Default-Values like this:
static PieMenu()
{
LeftSubItemsProperty = DependencyProperty.Register(
"LeftSubItems", typeof (ObservableCollection),
typeof (PieMenu), new UIPropertyMetadata(
new ObservableCollection()));
...
}
I developed, made some UI-Tests, developed, made some UI-Tests and so on and everything was fine. But only till I’ve placed a second PieMenu in my Test-App. All Items of PieMenu1 and PieMenu2 were contained in PieMenu1 and PieMenu2. If you see the line above you can image what happened, if you sit in front of your code with at least 1000 lines of code in the PieMenu-class, you have to search a bit.
In the line above the ObservableCollection created as a Default-Value for the Dependency-Property is of course a static one, because the Dependency-Property is stored in a static variable and as you see in the code-snippet above it is initialized in the static constructor of the PieMenu-class. There’s no instance around at this point.
In other words that means every PieMenu that won’t explicitly specify an ObservableCollection gets the Default-Value, and that’s a static one that will be shared over all PieMenus in your app. So all the Items of every PieMenu are in every PieMenu. Isn’t that amazing? :-)
The solution I’ve used is straight forward. Just create the Dependency-Property with a null-reference as its default-value:
static PieMenu()
{
LeftItemProperty = DependencyProperty.Register(
"LeftItem", typeof (PieMenuItem), typeof (PieMenu),
new UIPropertyMetadata(null));
}
In the Instance-Constructor assign a new ObservableCollection to the Dependency-Property and you’re fine.
public PieMenu()
{
LeftSubItems = new ObservableCollection();
...
}
Keep in mind that setting a local value in the Constructor won’t let you set this value in a Style anymore. But for the PieMenu and the ObservableCollection that won’t matter. You’re just adding and removing elements, you don’t want to define this Collection in a Style.
So, as you see in this post, you’ve to implement Dependency-Properties with Default-Values that are reference-types with caution.
Happy coding! ;-)
Comments (5)
Sweet PieMenu *thumbs up* I am wondering if you have added some animations?
Philip
Thanks. Of course I have added some animations. :-)
Awesome! thanks for the tip!!! I used it and it fixed my issue :D
Great it helped, thanks for the feedback Barak
Genau heute bin ich in diese Falle getappt *lach*. Dein Tipp war gold wert. Vielen Dank dafür.
VG R.