Я хочу переключать привязки текста и команд для кнопки на основе свойства VM.Connected.
По какой-то причине кнопка, кажется, "теряет" свою привязку к команде после второго щелчка.(т. е. Соединить -> Разъединить -> Соединить -> Не вызывает -> VM.Connect)
Кроме того, ActivityIndicatordoes не отображается и не запускается, когда IsBusy имеет значение true;
Просмотр XAML
<Button>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger TargetType="Button" Binding="{Binding Connected}" Value="False">
<Setter Property="Text" Value="Connect"/>
<Setter Property="Command" Value="{Binding Connect}"/>
</DataTrigger>
<DataTrigger TargetType="Button" Binding="{Binding Connected}" Value="True">
<Setter Property="Text" Value="Disconnect"/>
<Setter Property="Command" Value="{Binding Disconnect}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" Color="DarkBlue"/>
Просмотр модели
protected INavigationService NavigationService { get; private set; }
protected ICommunicationService CommunicationService;
private ObservableAsPropertyHelper<bool> _isBusy;
public bool IsBusy => _isBusy.Value;
private ObservableAsPropertyHelper<bool> _connected;
public bool Connected => _connected.Value;
public ReactiveCommand<Unit, bool> Connect { get; }
public ReactiveCommand<Unit, bool> Disconnect { get; }
public MainPageViewModel(INavigationService navigationService, ICommunicationService communicationService)
{
CommunicationService = communicationService;
NavigationService = navigationService;
_isBusy = this
.WhenAnyObservable(x => x.Connect.IsExecuting)
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.IsBusy, false);
_connected = this
.WhenAnyValue(x => x.CommunicationService.Connected)
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.Connected, false);
Connect = ReactiveCommand.CreateFromTask(
CommunicationService.ConnectAsync,
this.WhenAnyValue(
x => x.IsBusy, y => y.Connected,
(isBusy, isConnected) => CanConnect(isBusy,isConnected))
.ObserveOn(RxApp.MainThreadScheduler));
Disconnect = ReactiveCommand.CreateFromTask(
CommunicationService.DisconnectAsync,
this.WhenAnyValue(
x => x.IsBusy, y => y.Connected,
(isBusy, isConnected) => CanDisonnect(isBusy, isConnected))
.ObserveOn(RxApp.MainThreadScheduler));
}
private bool CanConnect(bool isBusy, bool isConnected)
{
return !isBusy && !isConnected;
}
private bool CanDisonnect(bool isBusy, bool isConnected)
{
return !isBusy && isConnected;
}
Сервисная модель
public interface ICommunicationService
{
bool Connected { get; }
Task<bool> ConnectAsync();
Task<bool> DisconnectAsync();
}
public class CommunicationService : ReactiveObject, ICommunicationService
{
private bool _connected;
public bool Connected { get => _connected; private set => this.RaiseAndSetIfChanged(ref _connected, value); }
public async Task<bool> ConnectAsync()
{
await Task.Delay(1000);
Connected = true;
return Connected;
}
public async Task<bool> DisconnectAsync()
{
await Task.Delay(1000);
Connected = false;
return Connected;
}
}