diff --git a/src/Elmish.WPF/Binding.fs b/src/Elmish.WPF/Binding.fs index d3c07694..ab30862e 100644 --- a/src/Elmish.WPF/Binding.fs +++ b/src/Elmish.WPF/Binding.fs @@ -125,6 +125,22 @@ module Binding = let id<'a> : string -> Binding<'a, 'a, 'a> = TwoWay.id |> createBindingT + + /// + /// The strongly-typed counterpart of Binding.oneWaySeq with parameter getId. + /// Exposes an ObservableCollection of child items for binding. + /// Allows a more efficient update than would be possible without using ids. + /// + module OneWaySeqT = + + /// + /// Elemental instance of a OneWaySeqT binding + /// + /// Defines whether an item is "equal" and needs to be updated if the ids are the same + /// Unique identifier for each item in the list (for efficient updates). + let id itemEquals (getId: 'a -> 'id) : string -> Binding<_, 'msg, _> = + OneWaySeq.create itemEquals getId + |> createBindingT /// /// Strongly-typed bindings that dispatch messages from the view. diff --git a/src/Samples/SubModelStatic.Core/Program.fs b/src/Samples/SubModelStatic.Core/Program.fs index 297e7d08..c983a4eb 100644 --- a/src/Samples/SubModelStatic.Core/Program.fs +++ b/src/Samples/SubModelStatic.Core/Program.fs @@ -11,7 +11,8 @@ module Counter = type Model = { Count: int - StepSize: int } + StepSize: int + History: (int * int) list } type Msg = | Increment @@ -21,14 +22,15 @@ module Counter = let init = { Count = 0 - StepSize = 1 } + StepSize = 1 + History = [] } let canReset = (<>) init let update msg m = match msg with - | Increment -> { m with Count = m.Count + m.StepSize } - | Decrement -> { m with Count = m.Count - m.StepSize } + | Increment -> { m with Count = m.Count + m.StepSize; History = (m.Count, m.History.Length) :: m.History } + | Decrement -> { m with Count = m.Count - m.StepSize; History = (m.Count, m.History.Length) :: m.History } | SetStepSize x -> { m with StepSize = x } | Reset -> init @@ -41,7 +43,7 @@ type [] CounterViewModel (args) = >> Binding.mapModel (fun (m: Counter.Model) -> m.StepSize) >> Binding.mapMsg Counter.Msg.SetStepSize - new() = CounterViewModel(Counter.init |> ViewModelArgs.simple) + new() = CounterViewModel({ Counter.init with History = [ (3,1); (0,0) ] } |> ViewModelArgs.simple) member _.StepSize with get() = base.Get() stepSizeBinding @@ -50,6 +52,7 @@ type [] CounterViewModel (args) = member _.Increment = base.Get() (Binding.CmdT.setAlways Counter.Increment) member _.Decrement = base.Get() (Binding.CmdT.setAlways Counter.Decrement) member _.Reset = base.Get() (Binding.CmdT.set Counter.canReset Counter.Reset) + member _.History = base.Get() (Binding.OneWaySeqT.id (=) snd >> Binding.mapModel (fun m -> m.History)) module Clock = diff --git a/src/Samples/SubModelStatic/Counter.xaml b/src/Samples/SubModelStatic/Counter.xaml index 2fa11674..5551966d 100644 --- a/src/Samples/SubModelStatic/Counter.xaml +++ b/src/Samples/SubModelStatic/Counter.xaml @@ -6,12 +6,37 @@ xmlns:vm="clr-namespace:Elmish.WPF.Samples.SubModelStatic;assembly=SubModelStatic.Core" mc:Ignorable="d" d:DataContext="{d:DesignInstance Type=vm:CounterViewModel, IsDesignTimeCreatable=True}"> - - -