Permalink
Browse files

User provided initial state for ReactiveCommands

ReactiveCommands when driven by an IObservable defaults initially
to reporting CanExecute as true before any events pass through the
canExecute observable.  This change keeps that default behavior, but
allows the user to change this default to false if appropriate.
  • Loading branch information...
sillyotter committed Jan 10, 2013
1 parent 07b99f7 commit d459eaabc02f73d435896ed95d9ec37960cdabe9
@@ -511,5 +511,50 @@ public void ReactiveAsyncCommandInitialConditionNewBehavior()
Assert.True(fixture.CanExecute(null));
});
}
+
+ [Fact]
+ public void ReactiveCommandInitialConditionDefaultBehavior()
+ {
+ (new TestScheduler()).With(sched =>
+ {
+ var canExecute = sched.CreateHotObservable(
+ sched.OnNextAt(0, false),
+ sched.OnNextAt(250, true)
+ );
+
+ var fixture = new ReactiveCommand(canExecute);
+
+ Assert.True(fixture.CanExecute(null));
+
+ sched.AdvanceToMs(10);
+ Assert.False(fixture.CanExecute(null));
+
+ sched.AdvanceToMs(255);
+ Assert.True(fixture.CanExecute(null));
+ });
+ }
+
+
+ [Fact]
+ public void ReactiveCommandInitialConditionNewBehavior()
+ {
+ (new TestScheduler()).With(sched =>
+ {
+ var canExecute = sched.CreateHotObservable(
+ sched.OnNextAt(0, false),
+ sched.OnNextAt(250, true)
+ );
+
+ var fixture = new ReactiveCommand(canExecute, initialCondition:false);
+
+ Assert.False(fixture.CanExecute(null));
+
+ sched.AdvanceToMs(10);
+ Assert.False(fixture.CanExecute(null));
+
+ sched.AdvanceToMs(255);
+ Assert.True(fixture.CanExecute(null));
+ });
+ }
}
}
@@ -31,6 +31,7 @@ public class ReactiveAsyncCommand : IReactiveAsyncCommand, IDisposable, IEnableL
/// operations at a time - defaults to one.</param>
/// <param name="scheduler">The scheduler to run the asynchronous
/// operations on - defaults to the Taskpool scheduler.</param>
+ /// <param name="initialCondition">Initial CanExecute state</param>
public ReactiveAsyncCommand(
IObservable<bool> canExecute = null,
int maximumConcurrent = 1,
@@ -28,11 +28,12 @@ public class ReactiveCommand : IReactiveCommand, IDisposable, IEnableLogger
/// execute.</param>
/// <param name="scheduler">The scheduler to publish events on - default
/// is RxApp.DeferredScheduler.</param>
- public ReactiveCommand(IObservable<bool> canExecute = null, IScheduler scheduler = null)
+ /// <param name="initialCondition">Initial CanExecute state</param>
+ public ReactiveCommand(IObservable<bool> canExecute = null, IScheduler scheduler = null, bool initialCondition = true)
{
canExecute = canExecute ?? Observable.Return(true).Concat(Observable.Never<bool>());
canExecute = canExecute.ObserveOn(scheduler ?? RxApp.DeferredScheduler);
- commonCtor(scheduler);
+ commonCtor(scheduler, initialCondition);
_inner = canExecute.Subscribe(
_canExecuteSubject.OnNext,
@@ -109,14 +110,14 @@ protected ReactiveCommand(Func<object, bool> canExecute, IScheduler scheduler =
public IObservable<Exception> ThrownExceptions { get; protected set; }
- void commonCtor(IScheduler scheduler)
+ void commonCtor(IScheduler scheduler, bool initialCondition = true)
{
this.scheduler = scheduler ?? RxApp.DeferredScheduler;
_canExecuteSubject = new ScheduledSubject<bool>(RxApp.DeferredScheduler);
canExecuteLatest = new ObservableAsPropertyHelper<bool>(_canExecuteSubject,
b => { if (CanExecuteChanged != null) CanExecuteChanged(this, EventArgs.Empty); },
- true, scheduler);
+ initialCondition, scheduler);
_canExecuteProbed = new Subject<object>();
executeSubject = new Subject<object>();

0 comments on commit d459eaa

Please sign in to comment.