wchtej
wchtej

Reputation: 15

ReactiveUI WhenAnyObservable doesn't work for me

My app is a winforms application and it references ReactiveUI 6.5. I'm trying to close window when user type "Exit" in a TextBox, but for some reason nothing happens.

This is my View:

public partial class HomeView : Form, IViewFor<HomeViewModel>
{
    public HomeView()
    {
        InitializeComponent();
        ViewModel = new HomeViewModel();

        this.Bind(ViewModel, x => x.EnteredText, x => x.textBox.Text);
        this.ViewModel.WhenAnyObservable(x => x.ExitCmd).Subscribe(_ => this.Close());

    }

    object IViewFor.ViewModel
    {
        get { return ViewModel; }
        set { ViewModel = (HomeViewModel)value; }
    }

    public HomeViewModel ViewModel { get; set; }
}

And this is my ViewModel:

 public class HomeViewModel : ReactiveUI.ReactiveObject
{
    string _text;
    public string EnteredText
    {
        get { return _text; }
        set { this.RaiseAndSetIfChanged(ref _text, value); }
    }

    public ReactiveCommand<object> ExitCmd { get; private set; }

    public HomeViewModel()
    {
        ExitCmd = ReactiveCommand.Create(this.WhenAny(x => x.EnteredText, y => y.Value == "Exit"));
    }
}

Upvotes: 1

Views: 676

Answers (2)

moswald
moswald

Reputation: 11667

You've almost got it, except nothing is telling your ExitCmd to Execute. The value you're passing to ReactiveCommand.Create is the canExecute property. You should change it to this:

ExitCmd = ReactiveCommand.Create();
this.WhenAnyValue(x => x.EnteredText)
    .Where(x => x == "Exit")
    .InvokeCommand(ExitCmd);

InvokeCommand actually executes the command parameter, passing each value from the observable sequence into the ExecuteAsync method as the parameter.

Upvotes: 0

Kuroro
Kuroro

Reputation: 1931

In your ViewModel, you should describe the relationship between your Exit Command and EntertedText

public class HomeViewModel : ReactiveUI.ReactiveObject
        {
            private string _text;
            public string EnteredText
            {
                get { return _text; }
                set { this.RaiseAndSetIfChanged(ref _text, value); }
            }

            public ReactiveCommand<object> ExitCmd { get; private set; }

            public HomeViewModel()
            {
                ExitCmd = ReactiveCommand.Create();
                this.WhenAny (x => x.EnteredText, x => x.Value == "Exit")
                .Where(k => k == true)
                .DistinctUntilChanged()
                .InvokeCommand (ExitCmd);
            }
        }

Then in your view, you can simply subscribe it

public partial class HomeView : Form, IViewFor<HomeViewModel>
{
    public HomeView()
    {
        InitializeComponent();
        ViewModel = new HomeViewModel();

        this.Bind(ViewModel, x => x.EnteredText, x => x.textBox.Text);
        this.ViewModel.ExitCmd.Subscribe (_ => this.Close());

    }

    object IViewFor.ViewModel
    {
        get { return ViewModel; }
        set { ViewModel = (HomeViewModel)value; }
    }

    public HomeViewModel ViewModel { get; set; }
}

Upvotes: 1

Related Questions