icn
icn

Reputation: 2363

How to assign a function for canExecute in ReactiveCommand in ReactiveUI?

I have recently started learning reactive extensions and not an expert on Rx. However, I am changing a previously written application into Reactive UI. But, when I wanted to change a RelayCommand to ReactiveCommand<Unit, Unit>, I faced this error:

System.NotSupportedException: 'Index expressions are only supported with constants. My RelayCommand was defined as bellow:

DownloadCmd = new RelayCommand(async x=> await DownloadSubtitle(), CheckYoutubeLink);

I changed it with a Reactive Command as follow:

var can = this.WhenAnyObservable(x=>Observable.Return(x.CheckYoutubeLink()));
DownloadCmd = ReactiveCommand.CreateFromTask(_ => DownloadSubtitle(),can);

Unfortunately, it does not work. In other words, my question is how to use a function (Func) for "canExecute" parameters or something that behaves like functions. By the way, I do not prefer to use Properties instead of functions since I have to write many properties for my commands. I have checked this link: ReactiveUI: Using CanExecute with a ReactiveCommand however, it cannot help me a lot.

Upvotes: 2

Views: 2021

Answers (1)

D&#246;harrrck
D&#246;harrrck

Reputation: 687

Based on the assumption that I made in my comment, a solution could look like this:

    public ViewModel()
    {
        this
            .WhenAnyValue(x => x.CurrentLink)
            .Subscribe(_ => CheckYoutubeLink());

        var can = this
            .WhenAnyValue(x => x.IsLinkValid);

        DownloadCmd = ReactiveCommand.CreateFromTask(_ => DownloadSubtitle(), can);
    }


    public ICommand DownloadCmd { get; private set; }

    [Reactive]
    public string CurrentLink { get; set; }

    [Reactive]
    public bool IsLinkValid { get; set; }

    private Task<object> DownloadSubtitle()
    {
        // your logic here
    }

    private void CheckYoutubeLink()
    {
        // your logic here
        IsLinkValid = CurrentLink != null && CurrentLink.Contains("youtube");
    }

As I said, I don't know what your application looks like but you just have to call CheckYoutubeLink whenever you set the link.

Upvotes: 2

Related Questions