DependencyProperty定義の記述量削減(F#)

下記記事にてC#でDependencyPropertyの記述量を削減してみました。
DependencyProperty定義の記述量削減 - 何でもプログラミング

今回はF#でDependencyPropertyの記述量を削減してみたいと思います。

内容はほぼAttachedPropertyの時と同じですので、下記記事も参考にしてみてください。
AttachedProperty定義の記述量削減(F#) - 何でもプログラミング

DependencyProperty管理クラス

Register、Get、Set、Changedを管理するクラスになります。

メモリリークしないよう、Changedで利用するEventは、ConditionalWeakTableに配置してあります。

member valで定義されたものは末尾に@が自動で付与されるので、"Property@"となっています。

type DependencyProperty<'owner, 'value when 'owner :> DependencyObject and 'owner : not struct>() =
    let mutable property : DependencyProperty = null
    let table = ConditionalWeakTable<'owner, Event<'value>>()
    member this.Register(?defaultValue : 'value, [<CallerMemberName>]?propertyName : string) =
        assert (property = null)
        let name = propertyName.Value.Substring(0, propertyName.Value.Length - "Property@".Length)
        let metadata = PropertyMetadata(defaultValue |> Option.defaultValue(Unchecked.defaultof<'value>), 
                                        PropertyChangedCallback(fun obj args -> match table.TryGetValue(obj :?> 'owner) with
                                                                                | true, ev -> ev.Trigger(args.NewValue :?> 'value)
                                                                                | false, _ -> () ))
        property <- DependencyProperty.Register(name, typeof<'value>, typeof<'owner>, metadata)
        property
    member this.Get(obj : 'owner) = obj.GetValue(property) :?> 'value
    member this.Set(obj : 'owner, value : 'value) = obj.SetValue(property, value)
    member this.Changed(obj : 'owner) = table.GetOrCreateValue(obj).Publish


利用例

上記クラスを利用すると、下記のようなコードになります。

毎回ownerクラスを指定したくない場合は、一段クラスか関数をかましてください。

type MyControl() as this =
    inherit UserControl()
    static let value = DependencyProperty<MyControl, int>()
    do  value.Changed(this).Add( (* 処理 *) )

    static member val ValueProperty = value.Register()
    member this.Value with get() = value.Get(this) and set(x) = value.Set(this, x)