Skip to content

Commit

Permalink
Work around broken ObservableForDP in WinRT
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Betts committed Jun 24, 2012
1 parent a626885 commit de77e01
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 22 deletions.
45 changes: 29 additions & 16 deletions ReactiveUI.Routing/RoutedViewHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Windows;
using ReactiveUI;
Expand Down Expand Up @@ -33,7 +34,9 @@ public RoutingState Router {
set { SetValue(RouterProperty, value); }
}
public static readonly DependencyProperty RouterProperty =
DependencyProperty.Register("Router", typeof(RoutingState), typeof(RoutedViewHost), new PropertyMetadata(null));
DependencyProperty.Register("Router", typeof(RoutingState), typeof(RoutedViewHost), new PropertyMetadata(null, routerChanged));

readonly Subject<RoutingState> routerChange;

/// <summary>
/// This content is displayed whenever there is no page currently
Expand All @@ -48,24 +51,34 @@ public object DefaultContent {

public RoutedViewHost()
{
this.ObservableFromDP(x => x.Router)
.Subscribe(x => {
if (_inner != null) {
_inner.Dispose();
_inner = null;
}
routerChange = new Subject<RoutingState>();

_inner = x.Value.ViewModelObservable().Subscribe(vm => {
if (vm == null) {
Content = DefaultContent;
return;
}
routerChange.Subscribe(x => {
if (_inner != null) {
_inner.Dispose();
_inner = null;
}

_inner = x.ViewModelObservable().Subscribe(vm => {
if (vm == null) {
Content = DefaultContent;
return;
}

var view = RxRouting.ResolveView(vm);
view.ViewModel = vm;
Content = view;
});
var view = RxRouting.ResolveView(vm);
view.ViewModel = vm;
Content = view;
});
});
}

static void routerChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
// XXX: This is to work around the fact that ObservableFromDP
// is broken in WinRT
var This = ((RoutedViewHost) dependencyObject);
This.routerChange.OnNext(This.Router);
}

}
}
20 changes: 14 additions & 6 deletions ReactiveUI.Routing/ViewModelViewHost.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Windows;
using ReactiveUI.Xaml;

Expand Down Expand Up @@ -27,7 +29,9 @@ public IReactiveNotifyPropertyChanged ViewModel {
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(IReactiveNotifyPropertyChanged), typeof(ViewModelViewHost), new PropertyMetadata(null));
DependencyProperty.Register("ViewModel", typeof(IReactiveNotifyPropertyChanged), typeof(ViewModelViewHost), new PropertyMetadata(null, somethingChanged));

readonly Subject<Unit> updateViewModel = new Subject<Unit>();

/// <summary>
/// If no ViewModel is displayed, this content (i.e. a control) will be displayed.
Expand All @@ -37,14 +41,13 @@ public object DefaultContent {
set { SetValue(DefaultContentProperty, value); }
}
public static readonly DependencyProperty DefaultContentProperty =
DependencyProperty.Register("DefaultContent", typeof(object), typeof(ViewModelViewHost), new PropertyMetadata(null));
DependencyProperty.Register("DefaultContent", typeof(object), typeof(ViewModelViewHost), new PropertyMetadata(null, somethingChanged));

public ViewModelViewHost()
{
var latestViewModel = Observable.CombineLatest(
this.ObservableFromDP(x => x.ViewModel).Select(x => x.Value).StartWith((IReactiveNotifyPropertyChanged)null),
this.ObservableFromDP(x => x.DataContext).Select(x => x.Value).OfType<IReactiveNotifyPropertyChanged>().StartWith((IReactiveNotifyPropertyChanged)null),
(vm, dc) => vm ?? dc);
var latestViewModel = updateViewModel
.Select(_ => (IReactiveNotifyPropertyChanged)(ViewModel ?? DataContext))
.StartWith((IReactiveNotifyPropertyChanged) null);

latestViewModel.Subscribe(vm => {
if (vm == null) {
Expand All @@ -57,5 +60,10 @@ public ViewModelViewHost()
Content = view;
});
}

static void somethingChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
((ViewModelViewHost)dependencyObject).updateViewModel.OnNext(Unit.Default);
}
}
}

0 comments on commit de77e01

Please sign in to comment.