I want to pass a parameter from my View to my ViewModel when a ReactiveCommand is executed that is bound to a Control. The parameter should be of type IJcUser
So I define the Command like this:
public ReactiveCommand<IJcUser, Unit> UserTouchCommand;
UserTouchCommand = ReactiveCommand.CreateFromTask(user => RootViewModel.DisplayUserProfile(user));
The signature of DisplayUserProfile
looks like
Task DisplayUserProfile(IJcUser user);
But the compiler complains because user
is from type CancelationToken
and not as expected IJcUser
I finally I found a solution but don't understand why the first approach did not work.
UserTouchCommand = ReactiveCommand.CreateFromTask<IJcUser>(RootViewModel.DisplayUserProfile);
We pass into the ReactiveCommand an IObservable<bool> of when the ReactiveCommand should be allowed to be executed. The ReactiveCommand uses an IObservable eventing system to determine if execution should be allowed which differs from other frameworks where you might have the command continuous poll if execution is allowed.
You can do so by creating a command via ReactiveCommand.Create: // Creates a command with synchronous execution logic // which is always available for execution. var command = ReactiveCommand.Create ( () => Console.WriteLine ( "A reactive command is invoked!" ) );
ReactiveCommand is explicitly derived from the ICommand interface to avoid users accidentally calling the non-reactive style methods. The ICommand methods do not lend well to long-running and also asynchronous commands, such as those that perform I/O operations. The ICommand also focuses on an imperative style of execution over the reactive style.
// The Unit type is often used to denote the successfull completion // of a void-returning method (C#) or a sub procedure (VB). ReactiveCommand< int ,Unit> command = ReactiveCommand.Create< int > ( integer => Console.WriteLine (integer)); // This outputs: 42 command.Execute ( 42 ).Subscribe ();
I finally I found a solution but don't understand why the first approach did not work.
Because you are using the wrong overload of the ReactiveCommand.CreateFromTask
method. The delegate user => RootViewModel.DisplayUserProfile(user)
may be a Func<CancellationToken, Task>
or a Func<IJcUser, Task>
. The compiler cannot know which one unless you tell it:
Func<IJcUser, Task> x = user => DisplayUserProfile(user);
UserTouchCommand = ReactiveCommand.CreateFromTask(x);
Or you could be explicit about the type argument:
UserTouchCommand = ReactiveCommand.CreateFromTask<IJcUser>(DisplayUserProfile);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With