JordanMarr / ReactiveElmish.Avalonia

Static Avalonia views for Elmish programs
Other
92 stars 8 forks source link

Add AllowNullLiteral attribute on ReactiveElmishViewModel #51

Closed kgday closed 7 months ago

kgday commented 7 months ago

As things stand now, if you have a collection property in your view model of sub view models, each a descendant of ReactiveElmishViewmodel, and a selected property of same sub view model type. You cannot bind to a 'SelectedItem' property of a ListBox because it is a FSharpOptionType, unless you are allowed to set the selected item property to null. By adding the 'AllowNullLiteral' attribute to ReactiveElmishViewModel, we can use Option.toObj and Option.ofObj as the last step in our elmish view model binding for example


[<AllowNullLiteral>] //can only add this if the ancestor has it
type CustomerListItemViewModel(store: IStore<Model, Message>, customer: Customer) as this
    =
    inherit ReactiveElmishViewModel()   

    //etc

type CustomersViewModel () as this
    =
    inherit ReactiveElmishViewModel()

    let localStore =
        Program.mkAvaloniaProgram init update
        |> Program.withErrorHandler (fun (s, ex) -> logger.LogError $"Error in paging: {s} {ex}")
        |> Program.mkStore

    //stuff
    member this.Customers =
        this.BindKeyedList(
            localStore
            , _.Customers
            , map = fun customer -> new CustomerListItemViewModel(localStore, customer)
            , getKey = _.Id
            , sortBy = _.Name
        )

    member this.SelectedCustomer
        with get () =
            this.Bind(
                localStore,
                (fun c ->
                    c.SelectedCustomerId
                    |> Option.bind (fun customerId -> this.Customers |> Seq.tryFind (fun c -> c.Id = customerId))
                    |> Option.toObj)
            )
        and set (value: CustomerListItemViewModel) =
            value |> Option.ofObj |> Option.map _.Id |> SelectCustomer |> localStore.Dispatch
JordanMarr commented 7 months ago

Released as v1.2.0

kgday commented 7 months ago

Thank you so much.