diff --git a/ReactiveUI.Platforms/Xaml/CreatesCommandBinding.cs b/ReactiveUI.Platforms/Xaml/CreatesCommandBinding.cs index 9c675dae36..b752725343 100644 --- a/ReactiveUI.Platforms/Xaml/CreatesCommandBinding.cs +++ b/ReactiveUI.Platforms/Xaml/CreatesCommandBinding.cs @@ -50,7 +50,12 @@ public IDisposable BindCommandToObject(ICommand command, object target, IObserva .Select(x => new { EventInfo = type.GetRuntimeEvent(x.Item1), Args = x.Item2 }) .FirstOrDefault(x => x.EventInfo != null); - if (eventInfo == null) return null; + if (eventInfo == null) { + throw new Exception( + String.Format( + "Couldn't find a default event to bind to on {0}, specify an event expicitly", + target.GetType().FullName)); + } var mi = GetType().GetRuntimeMethods().First(x => x.Name == "BindCommandToObject" && x.IsGenericMethod); mi = mi.MakeGenericMethod(eventInfo.Args); @@ -128,4 +133,4 @@ public IDisposable BindCommandToObject(ICommand command, object targ return null; } } -} \ No newline at end of file +} diff --git a/ReactiveUI.Platforms/Xaml/RoutedViewHost.cs b/ReactiveUI.Platforms/Xaml/RoutedViewHost.cs index a62aa7ea4d..914597e35d 100644 --- a/ReactiveUI.Platforms/Xaml/RoutedViewHost.cs +++ b/ReactiveUI.Platforms/Xaml/RoutedViewHost.cs @@ -23,7 +23,7 @@ namespace ReactiveUI.Xaml /// the View and wire up the ViewModel whenever a new ViewModel is /// navigated to. Put this control as the only control in your Window. /// - public class RoutedViewHost : TransitioningContentControl + public class RoutedViewHost : TransitioningContentControl, IViewFor { IDisposable _inner = null; @@ -57,6 +57,9 @@ public IObservable ViewContractObservable { public IViewLocator ViewLocator { get; set; } + // NB: This is just a scam to get WhenActivated + object IViewFor.ViewModel { get; set; } + public RoutedViewHost() { HorizontalContentAlignment = HorizontalAlignment.Stretch; @@ -83,25 +86,27 @@ public RoutedViewHost() this.WhenAnyObservable(x => x.ViewContractObservable), (vm, contract) => Tuple.Create(vm, contract)); - // NB: The DistinctUntilChanged is useful because most views in - // WinRT will end up getting here twice - once for configuring - // the RoutedViewHost's ViewModel, and once on load via SizeChanged - vmAndContract.DistinctUntilChanged().Subscribe(x => { - if (x.Item1 == null) { - Content = DefaultContent; - return; - } - - var viewLocator = ViewLocator ?? ReactiveUI.ViewLocator.Current; - var view = viewLocator.ResolveView(x.Item1, x.Item2) ?? viewLocator.ResolveView(x.Item1, null); - - if (view == null) { - throw new Exception(String.Format("Couldn't find view for '{0}'.", x.Item1)); - } - - view.ViewModel = x.Item1; - Content = view; - }, ex => RxApp.DefaultExceptionHandler.OnNext(ex)); + this.WhenActivated(d => { + // NB: The DistinctUntilChanged is useful because most views in + // WinRT will end up getting here twice - once for configuring + // the RoutedViewHost's ViewModel, and once on load via SizeChanged + d(vmAndContract.DistinctUntilChanged().Subscribe(x => { + if (x.Item1 == null) { + Content = DefaultContent; + return; + } + + var viewLocator = ViewLocator ?? ReactiveUI.ViewLocator.Current; + var view = viewLocator.ResolveView(x.Item1, x.Item2) ?? viewLocator.ResolveView(x.Item1, null); + + if (view == null) { + throw new Exception(String.Format("Couldn't find view for '{0}'.", x.Item1)); + } + + view.ViewModel = x.Item1; + Content = view; + }, ex => RxApp.DefaultExceptionHandler.OnNext(ex))); + }); } } }