Open adamhewitt627 opened 1 year ago
Suggestion...
Perhaps if there was an interface:
public interface ISynchronizationContextProvider
{
SynchronizationContext SynchronizationContext { get; }
}
Then a constructor could be added to RelayCommand
that would accept an instance of ISynchronizationContextProvider
.
ISynchronizationContextProvider
was provided, it can dispatch the NotifyCanExecuteChanged
to the given SynchronizationContext
.ISynchronizationContextProvider
was provided, then there would be no change in behavior.
Overview
This might be a better request for WPF, but (as I don't see that changing) I thought I would suggest it here.
Problem: as a developer, I want to use async code and be able to change properties and update command states without thinking about a
Dispatcher
.Binding
handles property changes regardless of the thread, so that's fine.CanExecuteChanged
throws if you raise the event on a background thread.This requires coupling your ViewModel to a dispatcher (or an
IDispatcher
) and limits the value of source generators like[NotifyCanExecuteChangedFor(nameof(MyCommand))]
. This becomes even more complex on platforms (e.g. UWP) where each window might have separate dispatchers.On a previous project, I ended up implementing my own
ICommand
that would capture theSynchronizationContext
during event registration and post back to it when notifying. (x:Bind
on UWP has a similar failure forINotifyPropertyChanged
.)I must have done the
ICommand
inside that closed-source project rather than my library, but the approach I took is illustrated here: https://github.com/adamhewitt627/SynchronizedEventsAPI breakdown
No new API is proposed here, I would like it to just be a behavior change.
Usage example
The usage would be the same:
MyCommand.NotifyCanExecuteChanged
.Breaking change?
I'm not sure
Alternatives
The developer can inject a dispatcher into a view model and marshal to the UI thread on their own.
Additional context
No response
Help us help you
No, just wanted to propose this