Seiten

Freitag, 21. Januar 2011

Wpf INotifyPropertyChanged mit F# Quotations.

Man implementiert die INotifyPropertyChanged-Schnittstelle um die Änderungen an einer Eigenschaft den Clients mitzuteilen. Standardmäßig verwendet man den Namen der Eigenschaft als einer String-Konstante, die an das PropertyChanged-Erreignis übergeben wird. Ungefähr so.
//standard version. pass property name as a string to the PropertyChanged event.
open System.ComponentModel
type ViewModelBase() =
    let propertyChangedEvent = new Event<PropertyChangedEventHandler, PropertyChangedEventArgs>()
    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChangedEvent.Publish
    member x.RaisePropertyChangedEvent (propertyName) = 
        if not(propertyName = null) then
            propertyChangedEvent.Trigger(x, new PropertyChangedEventArgs(propertyName))

type ResultViewModel (d:DateTime, name) =
    inherit ViewModelBase ()
    let mutable birthday = d
    let mutable name = name

    new () = new ResultViewModel(DateTime.Today, "")      

    member r.Birthday with get() = birthday
                       and set newValue =
                            birthday <- newValue
                            base.RaisePropertyChangedEvent("Birthday")

    member r.Name with get() = name
                       and set newValue =
                            name <- newValue
                            base.RaisePropertyChangedEvent("Name")
Alternativ kann man F#-Quotations an den RaisePropertyChangedEvent-Aufruf übergeben. Der Vorteil ist das wir  weg von den String-Konstanten sind, bei denen man schnell vertippen kann und der Compiler zur Kompilierzeit dies nicht merkt.
//version with F#-quotations
open System.ComponentModel
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

type ViewModelBase() =
    let propertyChangedEvent = new Event<PropertyChangedEventHandler, PropertyChangedEventArgs>()
    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChangedEvent.Publish
    member x.RaisePropertyChangedEvent (expr: Expr) = 
        match expr with
        | PropertyGet(_, methodInfo, _) ->
            let propertyName = methodInfo.Name
            propertyChangedEvent.Trigger(x, new PropertyChangedEventArgs(propertyName))
        | other -> failwith "not implemented" 

type ResultViewModel (d:DateTime, name) =
    inherit ViewModelBase ()
    let mutable birthday = d
    let mutable name = name

    new () = new ResultViewModel(DateTime.Today, "")      

    member r.Birthday with get() = birthday
                       and set newValue =
                            birthday <- newValue
                            base.RaisePropertyChangedEvent(<@r.Birthday@>)

    member r.Name with get() = name
                       and set newValue =
                            name <- newValue
                            base.RaisePropertyChangedEvent(<@r.Name@>)

Keine Kommentare:

Kommentar veröffentlichen