This is a quick post to share on how-to declare WPF / Silverlight DependencyProperty in F#. The reason, In F# there are no public static fields to declare. Read all about DPs (DependencyProperty in short) here. If you are developing a WPF / Silverlight solution libraries completely in F#, then you would have to declare DPs so you can expose the functionality to be used in any .NET language.
Let’s say we have an ItemsSource property to declare, below is the way it has to be declared,
[<DefaultValue>] static val mutable private ItemsSourcePropertyInternal : DependencyProperty static member ItemsSourceProperty with get() = if CustomControl.ItemsSourcePropertyInternal = null then CustomControl.ItemsSourcePropertyInternal <- DependencyProperty.Register("ItemsSource", typeof<IEnumerable>, typeof<CustomControl>, new PropertyMetadata(null)) CustomControl.ItemsSourcePropertyInternal member x.ItemsSource with get() = x.GetValue(CustomControl.ItemsSourceProperty) : ? > IEnumerable and set(v : IEnumerable) = x.SetValue(CustomControl.ItemsSourceProperty, v)
- Declare a private mutable variable that registers the DependencyProperty
- Write a static member variable with a getter that initializes the DP
- Declare the member property with a getter and setter.
- Important thing to note in the setter is to decorate the value “v” with the type. This is because of the fact that when this property gets exposed to other .NET languages like C# or VB, it causes errors assigning un-typed values to the property.
In WPF, there is a caveat. WPF can invoke private / internal field variables too from XAML, rather Silverlight can only invoke public variables from XAML. So we don’t require the notion of creating a private mutable static field (If we don’t wish to expose it). The same ItemsSource property can be declared as below In WPF,
static let ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof<IEnumerable>, typeof<SearchTwitterBox>, new PropertyMetadata(null)) member x.ItemsSource with get() = x.GetValue(ItemsSourceProperty) : ? > IEnumerable and set(v : IEnumerable) = x.SetValue(ItemsSourceProperty, v)
We won’t be able to expose the DP here, but it does work if you don’t want to expose the DP.