I am trying to hook a stream (IObservable
) to be controlled through ToggleSwitch
in a UWP project. The expectation is that I start the streaming when the switch is in On
state and stop when it is in Off
state.
So the thought is to
1. Create two commands, one to start the stream and another to stop the stream.
2. Create two Observables that monitors the switch state and InvokeCommand
when the condition is right.
ViewModel
public class MainPageViewModel : ViewModelBase
{
public ReactiveCommand<Unit, (long, float)> StreamCommand { get; }
public ReactiveCommand<Unit, Unit> StopCommand { get; }
public IObservable<(long, float)> FlowStream { get; set; }
private bool _isStreamOn;
public bool IsStreamOn
{
get => _isStreamOn;
set => this.RaiseAndSetIfChanged(ref _isStreamOn, value);
}
public MainPageViewModel()
{
var stream = GetStream();
var canSwitchOn = this.WhenAnyValue(x => x.IsStreamOn);
var canSwitchOff = this.WhenAnyValue(x => x.IsStreamOn, isOn => isOn != true);
FlowStream = StreamCommand = ReactiveCommand.CreateFromObservable(
() =>
{
stream.Start();
return Observable.FromEventPattern<StreamDataEventArgs<(long, INumeric, INumeric, INumeric)>>(
h => stream.DataAvailable += h,
h => stream.DataAvailable -= h)
.SelectMany(e => e.EventArgs.Data)
.Select(item => item));
}, canSwitchOn);
StopCommand = ReactiveCommand.Create(
() =>
{
stream.Stop();
IsStreamOn = false;
}, canSwitchOff);
canSwitchOff.InvokeCommand(StopCommand);
canSwitchOn.InvokeCommand(StreamCommand);
}
}
View
public sealed partial class MainPage : Page, IViewFor<MainPageViewModel>
{
public MainPage()
{
InitializeComponent();
NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
ViewModel = new MainPageViewModel();
this.WhenActivated(subscription =>
{
subscription(this.OneWayBind(this.ViewModel,
vm => vm.StreamCommand,
v => v.chart.SeriesCollection[0].Stream)); // Chart take care of displaying data
subscription(this.Bind(this.ViewModel,
vm => vm.IsStreamOn,
v => v.streamToggle.IsOn));
});
}
object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (MainPageViewModel)value; }
}
public MainPageViewModel ViewModel
{
get { return (MainPageViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(MainPageViewModel), typeof(MainPage), null);
}
However, the InvokeCommand
fails, as it requires the ReactiveCommands to take the bool, instead of Unit
.
Any idea how I can invoke a command when certain conditions are met?