Sometimes you just gotta do the best you can [Tip: Read-only custom DependencyProperties don’t exist in Silverlight, but can be closely approximated]


This blog has moved to a new location and comments have been disabled.

All old posts, new posts, and comments can be found on The blog of dlaa.me.

See you there!

Comments (13)
  1. mstrobel says:

    Ugh.  How is it that we’re upon the 5th major release of Silverlight, and the core framework is still in a pre-alpha state?  We don’t have DP overrides, read-only DPs, triggers, setters, or routed events, but woohoo, we have 3D plane projections!

    The Silverlight PMs have done a woefully inept job of steering development, so why haven’t they all been replaced?

  2. Delay says:

    Mike Strobel,

    Sorry about the frustration! For what it’s worth, the Silverlight team tends to implement features based on how necessary they are for the current customer segment. In cases like this one where it’s possible to work around a missing feature (or very nearly so), it’s sometimes the case that some different feature gets prioritized higher because what that *other* feature enables is simply impossible without platform support. Therefore, while I miss read-only DependencyProperties, too, I wouldn’t read too far into the fact that they haven’t made it into Silverlight quite yet. 🙂

    Thanks for your comment!

  3. DrWPF says:

    If I need a bindable, readonly property on my Silverlight dependency object, I just use a readonly CLR property and raise a PropertyChanged event in my protected or private setter.

    You can’t set a binding on a readonly DP anyway… all you can do is make it the source for some OneWay binding on another DP.  So I just implement INotifyPropertyChanged on the dependency object, the same way I would for any other CLR object.  It works great, it’s lightweight, and it has much less overhead than trying to make a Silverlight DP behave as if it’s readonly.  😀

  4. Delay says:

    DrWPF,

    Wow, that is a great suggestion! I’m emailing you now to discuss a couple of things about it, but once that’s settled, it sounds like I need another DependencyProperty tip to discuss your solution.

    Thanks very much!

  5. SharpGIS says:

    There’s a MUCH easier way:

    [assembly: InternalsVisibleTo("System.Windows, PublicKey=00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb77e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c123b37ab")]

    public int MyReadOnly

    {

       get { return (int)GetValue(MyReadOnlyProperty); }

       private set

       {

              SetValue(MyReadOnlyProperty, value);

       }

    }

    internal static readonly DependencyProperty MyReadOnlyProperty = DependencyProperty.Register(

       "MyReadOnly", typeof(int), typeof(MyControl), new PropertyMetadata(0));

  6. SharpGIS says:

    btw are you now saying that it’s "illegal" to do this:

    myObject.SetValue(MyReadOnlyProperty,5) ?

  7. Delay says:

    SharpGIS,

    I’m saying that WPF will not allow "SetValue(MyReadOnlyProperty, 5)" to succeed on a read-only DependencyProperty (you need to use the private DependencyPropertyKey instead) and therefore that the same code should not work for "simulated read-only" properties on Silverlight, either.

    Regarding your InternalsVisibleTo suggestion, I’ve Twittered you just now to discuss this further. I’ll post a follow-up comment here after we’ve come to an agreement. 🙂

  8. Delay says:

    SharpGIS,

    Your InternalsVisibleTo solution excites and revolts me – at the same time. 🙂 I’ll be doing a follow-up blog post to this one and I’ll include your suggestion along with DrWPF’s.

    Thanks very much for sharing!

  9. DrWPF says:

    The biggest issue I see with your solution, SharpGIS, is that it does not create a readonly DP.  Your approach only makes it more difficult to modify the value, but its not a true readonly property.  For example, you can change the value of the DP by creating a two-way binding to the property and changing the bound value (e.g., bind the Text property of a TextBox to your property using a TwoWay binding and then change the text in the control and it will update your property).

  10. jariza says:

    Wouldn't that be a problem if you have several read-only properties in the same class? You might want to set other properties when one of them changes, so I would add

    _changingMyReadOnly = false;

    right before

    myControl.OnMyReadOnlyChanged((int)e.OldValue, (int)e.NewValue);

  11. Delay says:

    jariza,

    That's a great point, thanks for bringing it up! On the other hand, you might consider having a dedicated instance of the _changingMyReadOnly/_restoringMyReadOnly variables for each read-only DependencyProperty in a class so they're all truly independent. Without analyzing it too much, I feel like this latter approach might be a bit easier to get right and more straightforward to think about.

  12. wekempf says:

    DrWPF, as usual your suggestion is simple and functional. However, there's a minor hole. This solution won't work for readonly _attached_ properties. Honestly, most of my readonly DPs are attached DPs.

  13. weitzhandler says:

    Won't work on attached DPs though

Comments are closed.