Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the main drawbacks of exposing a DependencyProperty via a static property instead of a static field? (F#)

I found out that F# 2.0 apparently doesn't support public static fields anymore, which makes impossible the standard way of implementing a DependencyProperty:

public static readonly FooProperty = DependencyProperty.Register(...);   // in C#

I don't quite like one suggested work-around for F# which involves declaring the DependencyProperty as a static mutable val and then initializing it with a static do... (or however exactly it goes).

I've tried exposing a DependencyProperty as a public static property instead of as a public static field, which seems to work just fine in a WPF application (I've tried data binding and style setters on the property, both with success):

type XY() =
   inherit Control()

   static let fooProperty =
      DependencyProperty.Register("Foo", typeof<string>, typeof<XY>) 

   static member public FooProperty with get () = fooProperty  // see update below:
   //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  // not required!

   member public this.Foo with get (): string = this.GetValue(fooProperty) :?> string
                          and set (x: string) = this.SetValue(fooProperty, x)

Are there any notable drawbacks to publishing a dependency property as a property, instead of as a field? Because this code looks much cleaner to me than the suggested work-around.


Update #1: I just found that in the above code, FooProperty (the public read-only property) isn't even required. So one could drop the line I high-lighted in the above code example and things still work just fine. I'm now even more curious why people go to such lengths using mutable val etc. when it's apparently that simple? Am I missing something important?


Update #2: In a comment below, Robert Jeppesen provided a hyperlink to an MSDN page which mentions the following:

If you fail to follow this naming pattern [ie. FooFooProperty] , designers might not report your property correctly, and certain aspects of property system style application might not behave as expected.

I put Expression Blend 4 to the test and found that it doesn't seem to be affected at all when the public static FooProperty is completely missing.

like image 716
stakx - no longer contributing Avatar asked Nov 09 '10 17:11

stakx - no longer contributing


1 Answers

Yes, it does make a difference whether you use a public static field or not. But maybe not a significant difference, depending on your needs. I will explain where WPF itself behaves differently, then mention a couple of other situations in which it might also be a problem.

Effect on XAML parsing if you use a static property instead of a static field

The only part of WPF itself that actually notices whether you used a static property or a static field is the XAML parser, and the only situation where it makes a difference is when the same property name is used at multiple levels. This is because the existence of a static field with matching name and ending in "Property" is used to disambiguate between identically-named DependencyProperties at multiple levels.

One place you'll see a difference is if you define your property using a public static property (or nothing at all) and the ancestor class has a DependencyProperty the same name using a public static field, the ancestor class's property will be used instead of yours.

For example, suppose create a Control that has a DependencyProperty named "Language". FrameworkElement already has a "Language" DependencyProperty, but as long as you follow the standard and use a public static field, that's ok: Your "Language" property will take precedence. But if you use a public static property instead, your XAML will end up setting the "FrameworkElement.Language" dependency property, not yours.

This could be a problem if, for example, a new version of WPF comes out that has a new dependency property defined on one of your base classes. For example, if you are using a "Depth" property you've defined using a static field, and NET Framework 5.0 defines a "Depth" property on "Visual", your application won't work on the new version of NET Framework.

Another scenario where this may make a difference is when the class hierarchy is changed. WPF tries to protect you from versioning issues in this case, but its protection goes away if you used a public static property instead of a public static field. The simplest scenario is that you wrote a library and people are using your property. If you used a public static field their compiled application will actually include your class name so there can be no mistake. But if you used a public static property (or nothing at all) their compiled application will reference it using their derived class name. So if the inheritance hierarchy changes or a new property is introduced in between, it could shadow your original property even in compiled code. For example, this could be an issue if:

  • YourControl is derived from ThirdPartyGrid
  • YourControl was written when ThirdPartyGrid didn't have a "Language" field, so the compiled code references FrameworkElement.Language
  • If the vendor of ThirdPartyGrid adds a "Language" dependency property it won't affect your application
  • But if FrameworkElement.Language had been defined as a public static property, the vendor's addition would break your application

There are some even more esoteric situations where it can make a difference.

Effects on designer tools

As far as I can tell, neither Visual Studio nor Expression Blend behave any differently if you define the property using a public static property instead of a field, or even if you leave it out entirely, except when they encounter the XAML parser behavior mentioned earlier.

But it should be noted that there are many XAML development environments out there, and since the pattern of using static fields is so firmly established, they may rely on this. So it is caveat emptor.

Effects on WPF itself other than XAML parsing

Except for the XAML parser, no part of WPF cares whether you have defined a public static property, field, or nothing at all. You can use your DependencyProperties exactly the same way in each case. However:

  1. I know of no guarantee this will always be true, and
  2. Third party code could easily rely on it
like image 120
Ray Burns Avatar answered Sep 20 '22 13:09

Ray Burns