0
votes

I'm in favor of command binding in ReactiveUI and want to integrate into my current project, which based on MvvmCross.

I've followed the tutorial from Data Binding - WPF. I just modify View with IViewFor, but not ReactiveObject VIewModel because it inherits MvvmCross object.

Things working fine when I just bind command with basic set - Like ReactiveCommand.Create(TestCommand). But when I try to use one of the favorable feature, can execute (Create(command, canExecute), it doesn't work :(

It seems ViewModel = new TheViewModel(); in the tutorial just create another ViewModel instance for interaction. And any property change in my MvvmCross does not reflect to the ViewModel created in View.

So how to properly use ReactiveUI Command in MvvmCross WPF?

1
What are you using to generate your CanExecute?Glenn Watson
@GlennWatson , I've found the solution. BTW, I use this.WhenAnyValue to generate canExecute. Actually, there is wrong in tutorial: reactiveui.net/docs/handbook/data-binding/…. We can just use ReactiveCommand without modifying VIew if wanna integrate with MvvmCross. In short, 1. use databinding provided by MvvmCross in View; 2. use ReactiveUI Command in ViewModelimckl

1 Answers

0
votes

Description

I've figured out the solution and post here in case someone encounter such stuff.

The tutorial: https://reactiveui.net/docs/handbook/data-binding/windows-presentation-foundation is more about how to use ReactiveUI Binding in WPF, and i'm not sure it is the right way to do so when using ReactiveUI because it creates a new instance of the ViewModel. At least, this does not work with MvvmCross.

To use ReactiveUI Command in MvvmCross, we can create ReactiveCommand in ViewModel, and use MvvmCross-way to bind command.

ViewModel based on MvvmCross with ReactiveCommand

// ViewModel code like this:

public ReactiveCommand<Unit, Unit> DoSomethingCommand { get; }

public SomeViewModelConstructor(){
    var canExecuteDoSomethingCommand = this.WhenAnyValue(/* value condition stuff here */);
    DoSomethingCommand = ReactiveCommand.CreateFromTask(DoSomething, canExecuteDoSomethingCommand);
}

async Task DoSomehing(){
    await SomeService.DoSomething();
}

View based on MvvmCross with Fluent Binding (which is Type-Safe)

// Type-safe View code like this:

// in xaml
<Button Content="DoSomething" x:Name="ButtonDoSomething" />

// in xaml.cs
public SomeViewConstructor(){
    // type-safe binding
    using var set = this.CreateBindingSet<SomeView, SomeViewModel>();
    set.Bind(ButtonDoSomething)
        .For(v => v.Command)
        .To(vm => vm.DoSomethingCommand);
}