Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind Visibility to ReactiveCommand CanExecute

I have several Tiles (TileLayoutControl Class) in my xaml (only shown 2 in this example) whose Visibility are binded to Boolean Properties and converted through BooleanToVisibilityConverter.
This works just fine. My question is

Can I bind the visibility to the Command instead so that I can remove the need of those several Boolean Properties?

Something like binding the Visibility to Command.CanExecute

If Yes, How can I achieve that? Any help will be really appreciated! Thanks.

<dxlc:Tile Command="{Binding Tile1Command}"
           Visibility="{Binding Path=IsTile1Visible , Converter={StaticResource BooleanToVisibilityConverter}}"/>
<dxlc:Tile Command="{Binding Tile2Command}"
           Visibility="{Binding Path=IsTile2Visible , Converter={StaticResource BooleanToVisibilityConverter}}"/>

ViewModel

private bool _isTile1Visible;
public bool IsTile1Visible
{
    get { return _isTile1Visible; }
    set { this.RaiseAndSetIfChanged(ref _isTile1Visible, value); }
}

public ReactiveCommand Tile1Command { get; private set; }

Tile1Command = new ReactiveCommand();
Tile1Command.Subscribe(p => PerformTile1Operation());
like image 349
Butters Avatar asked Jan 11 '23 16:01

Butters


1 Answers

Yes, just use RxUI bindings:

<dxlc:Tile x:Name="Tile1" />

Then in your View constructor (make sure to implement IViewFor<Tile1ViewModel> to get this extension):

this.BindCommand(ViewModel, x => x.Tile1Command);

this.WhenAnyObservable(x => x.ViewModel.Tile1Command.CanExecuteObservable)
    .BindTo(this, x => x.Tile1.Visibility);

You could also solve this in the ViewModel level, though that's not what I would do - in the ViewModel ctor:

Tile1Command = new ReactiveCommand(/* ... */);
Tile1Command
    .Select(x => x ? Visibility.Visible : Visibility.Collapsed)
    .ToProperty(this, x => x.Tile1Visibility, out tile1Visibility);
like image 76
Ana Betts Avatar answered Jan 21 '23 23:01

Ana Betts