Search code examples
c#reactiveuiavaloniaui

ReactiveUI and CanExecute: How to validate boolean variables


Because of AvaloniaUI I am confronted with ReactiveCommands. While the excecution part is quite easy, I would like to manage the canexecute part. In particular, I need to check some boolean properties of a socket. As they change asynchronously, I would like to enable or disable a button accordingly. Lets say:

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        OnButton_Clicked = ReactiveCommand.Create(OnButtonClicked, CanClickButton);
    }
    
    private Socket Socket { get; set; }
    
    public ReactiveCommand<Unit, Unit> OnDiscover_Clicked { get; }
    
    private void OnButtonClicked()
    {
        // Do something
    }
    
    private bool CanClickButton()
    {
        return Socket?IsAvailable;
    }
}

Of course, it doesn't work like that. ReactiveCommand requieres some observeable object, which in turn seems to rely on IPropertyChanged, but that again is not provided by the Socket. How can I achieve a periodic check of a boolean variable in the canexecute function?


Solution

  • Like you stated in your question the ReactiveCommand requires an IObservable<bool>

    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            IObservable<bool> canExecute = this.WhenAnyValue(x => x.Socket.IsAvailable);
            OnDiscover_Clicked = ReactiveCommand.Create(OnButtonClicked, canExecute);
        }
    
        private Socket Socket { get; set;     }
    
        public ReactiveCommand<Unit, Unit> OnDiscover_Clicked { get; }
    
        private void OnButtonClicked()
        {
            // Do something
        }
    }
    

    Note that your socket class needs to implement INotifyPropertyChanged in order for this.WhenAnyValue to work, so you could create something like a SocketViewModel which wraps the socket.