ailon's DevBlog: Development related stuff in my life

Writing WPF/Silverlight compatible code. Part 5: Adding PropertyChangedCallback

11/30/2009 5:13:27 PM

Note for future readers: These series discuss WPF and Silverlight versions that are current stable versions at the time of this writing – WPF 3.5 and Silverlight 3.

These are ongoing series of posts on the subject of WPF/Silverlight compatibility. New posts will be added to the Table of Contents post as they are written so bookmark that post or just subscribe to my RSS feed.

No OverrideMetadata() Take 2

One thing I didn’t mention in the “No OverrideMetadata()” section of “Part 2: Dependency Properties” is how to add a handler to be called when value of inherited dependency property changes. In WPF you can use OverrideMetadata() method to do it like this:

   1: static MyControl()
   2: {
   3: #if !SILVERLIGHT
   4:     FrameworkPropertyMetadata newMetadata = new FrameworkPropertyMetadata();
   5:     newMetadata.PropertyChangedCallback += MyControl.VisibilityProperty_Changed;
   6:     Control.VisibilityProperty.OverrideMetadata(typeof(MyControl), newMetadata);
   7: #endif
   8: }

Then you do what you wanted to do in your handler which is called every time Visibility changes:

   1: private static void VisibilityProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
   2: {
   3:     // do something here
   4: }

As you know there’s no OverrideMetadata() in Silverlight. So what can we do? Unfortunately, to my knowledge, there’s no elegant way to do this. There are however a couple of not so pretty hacks/workarounds. One is described in an answer to a similar question on StackOverflow.

I’ve used another method which involves an extra DependencyProperty declaration and binding of the original dependency property to this one. In the above mentioned case a Silverlight portion for achieving the same result looks like this:

   1: #if SILVERLIGHT
   2:         // declare an extra DependencyProperty for the workaround
   3:         // It uses the same PropertyChangedCallback as WPF code for Visibility
   4:         private static readonly DependencyProperty VisibilityChangedWorkaroundProperty = DependencyProperty.Register(
   5:             "VisibilityChangedWorkaround", typeof(Visibility), typeof(MyControl),
   6:             new PropertyMetadata(MyControl.VisibilityProperty_Changed));
   7: #endif
   8:  
   9: public MyControl()
  10: {
  11: #if SILVERLIGHT
  12:     // visibility changed event workaround
  13:     Binding visibilityBnd = new Binding("Visibility");
  14:     visibilityBnd.Source = this;
  15:     visibilityBnd.Mode = BindingMode.TwoWay;
  16:     this.SetBinding(MyControl.VisibilityChangedWorkaroundProperty, visibilityBnd);
  17: #endif
  18: }

As you can see above, we’ve declared and extra dependency property called VisibilityChangedWorkaroundProperty and we’ve attached the same handler to it’s property changed event as the one used in the WPF code above. We don’t need a CLR property wrapper for it and we’ve declared it as private so it doesn’t show up anywhere outside of our class. Then in the constructor we bind our new workaround property to the real inherited Visibility property. So, when inherited property changes, our local property changes too, and the callback is called.

kick it on DotNetKicks.com Shout it

Comments

1/26/2010 7:14:01 PM

stavros sotirchos

This actually has a small flaw. I've implemented it in a usercontrol. I had the user control with visibility set to visible in the xaml and never got the changed handler called.

stavros sotirchos Greece

1/29/2010 9:45:40 AM

ailon

@stavros: the handler is called only when property value changes. If the default (or current) value is Visible and you set it to Visible again it is not treated as change.

ailon Lithuania

5/6/2010 11:30:41 AM

Ryan

You wouldn't believe how long I've sat here trying to figure out why I couldn't activate the handler...

Thanks

Ryan United States

8/27/2010 3:47:17 PM

annuaire généraliste

To "Ryan" : I also was trying and I could'nt activate the handler too.

Thanks

annuaire généraliste Belgium

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading



Copyright © 2003 - 2010 Alan Mendelevich
Powered by BlogEngine.NET 1.6.1.0