4

I was wondering what is the best way to bind the control properties to the CommandParameter in ReactiveUI?

The BindCommand below does not provide a way to pass the parameter. The overload either takes a property in view model or an IObservable<T> for parameters.

View

this.WhenActivated(subscription =>
{
    subscription(this.BindCommand(
                    this.ViewModel,
                    vm => vm.TextCommand,
                    v => v.ComboBox
                    ));
}

ViewModel

public class MainPageViewModel : ViewModelBase
{
    public ReactiveCommand<string, Unit> TextCommand { get; set; }


    public MainPageViewModel()
    {
        TextCommand = ReactiveCommand.CreateFromTask<string>(DoSomething);

    }

    private Task DoSomething(string selectedText)
    {
        return Task.Delay(3000);
    }
}

The DoSomething method is called with selectedText as null everytime.

I have tried passing the IObservable for ToggleSwitch, but the behaviour is not as expected.

View

IObservable<bool> toggleOn = this.WhenAnyValue(v => v.Toggle.IsOn);
this.WhenActivated(subscription =>
{
     subscription(this.BindCommand(
                this.ViewModel,
                vm => vm.ToggleCommand,
                v => v.Toggle, toggleOn));
}

ViewModel

ToggleCommand = ReactiveCommand.CreateFromTask<bool>(Toggled);

private Task Toggled(bool toggleState)
{
   return Task.Delay(3000);
}

In the above code I do managed to get the toggleState, but it is the last state not the new state of the ToggleSwitch. Also, I could not make this work of ComboBox. I think it is a very common to pass command parameters from view and there should be an easier way to achieve it. What am I missing? I am using UWP app.

Thanks

resp78
  • 1,414
  • 16
  • 37
  • Combobox's don't inheritantly have a "Command" though normally, is it you are attempting to trigger a command on the selected value changing? – Glenn Watson Oct 05 '17 at 04:44
  • You may be right, but the Command works as advertised. Whenever I change the selection in `ComboBox` or `ToggleSwitch` the command is executed. The question is how to pass a parameter to that command that is a property of a control, in the case of `ComboBox` it may be `SelectedItem` or in `ToggleSwitch` `IsOn`. – resp78 Oct 06 '17 at 00:10
  • 1
    Wouldn't be better to do a Binding to a property in your VM to the SelectedItem, then you can have a WhenAnyValue(x => x....).InvokeCommand() instead. Then you got full access to your property. That is if you need the Command due to a Task/Observable you need to await upon. – Glenn Watson Oct 06 '17 at 14:42
  • This looks like an acceptable way out. Let me try it – resp78 Oct 07 '17 at 10:57
  • This worked but had some side effects (maybe to do with my limited knowledge). `this.Bind(this.ViewModel, vm => vm.SelectedValue, v => v.ComboBox.SelectedValue)` leaks the `ComboBoxItem` in the view model. Only if there is a way to select the `Content` as `string` instead of `SelectedValue` – resp78 Oct 07 '17 at 11:50

1 Answers1

1

I guess you can only bind commands to events, not directly to properties (maybe I'm wrong).

What if you subscribe to the SelectedValueChanged (Can't remember the name of the event) event in the combobox and then fire the command manually?

this.ComboBox.Events().SelectedValueChanged
    .Select(_ => ComboBox.Text)
    .InvokeCommand(this, vm => vm.ViewModel.TextCommand);
Luis
  • 436
  • 4
  • 11