Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions ReactiveUI.Platforms/Xaml/CreatesCommandBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -128,4 +133,4 @@ public IDisposable BindCommandToObject<TEventArgs>(ICommand command, object targ
return null;
}
}
}
}
45 changes: 25 additions & 20 deletions ReactiveUI.Platforms/Xaml/RoutedViewHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
/// </summary>
public class RoutedViewHost : TransitioningContentControl
public class RoutedViewHost : TransitioningContentControl, IViewFor
{
IDisposable _inner = null;

Expand Down Expand Up @@ -57,6 +57,9 @@ public IObservable<string> 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;
Expand All @@ -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)));
});
}
}
}