From d0d1eb1ed2a2a6a1d2b27fcafbd3785cf9e6d6c2 Mon Sep 17 00:00:00 2001 From: Joshua Marner Date: Fri, 4 Nov 2022 22:23:57 -0500 Subject: [PATCH] Fix bug with events getting raised too soon --- src/Elmish.WPF/DynamicViewModel.fs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Elmish.WPF/DynamicViewModel.fs b/src/Elmish.WPF/DynamicViewModel.fs index 31a2493e..be723315 100644 --- a/src/Elmish.WPF/DynamicViewModel.fs +++ b/src/Elmish.WPF/DynamicViewModel.fs @@ -77,7 +77,12 @@ module internal ViewModelHelper = ErrorsChanged = DelegateEvent>() } - let updateModel newModel helper = + let getEventsToRaise newModel helper = + helper.Bindings + |> Seq.collect (fun (Kvp (name, binding)) -> Update(helper.LoggingArgs, name).Recursive(helper.Model, newModel, binding)) + |> Seq.toList + + let raiseEvents eventsToRaise helper = let { log = log nameChain = nameChain } = helper.LoggingArgs @@ -90,19 +95,13 @@ module internal ViewModelHelper = let raiseErrorsChanged name = log.LogTrace("[{BindingNameChain}] ErrorsChanged {BindingName}", nameChain, name) helper.ErrorsChanged.Trigger([| helper.GetSender (); box <| DataErrorsChangedEventArgs name |]) - - let eventsToRaise = - helper.Bindings - |> Seq.collect (fun (Kvp (name, binding)) -> Update(helper.LoggingArgs, name).Recursive(helper.Model, newModel, binding)) - |> Seq.toList + eventsToRaise |> List.iter (function | ErrorsChanged name -> raiseErrorsChanged name | PropertyChanged name -> raisePropertyChanged name | CanExecuteChanged cmd -> cmd |> raiseCanExecuteChanged) - { helper with Model = newModel } - type [] internal DynamicViewModel<'model, 'msg> ( args: ViewModelArgs<'model, 'msg>, bindings: Binding<'model, 'msg> list) @@ -168,7 +167,9 @@ type [] internal DynamicViewModel<'model, 'msg> member _.CurrentModel : 'model = helper.Model member _.UpdateModel (newModel: 'model) : unit = - helper <- ViewModelHelper.updateModel newModel helper + let eventsToRaise = ViewModelHelper.getEventsToRaise newModel helper + helper <- { helper with Model = newModel } + ViewModelHelper.raiseEvents eventsToRaise helper override _.TryGetMember (binder, result) = log.LogTrace("[{BindingNameChain}] TryGetMember {BindingName}", nameChain, binder.Name)