public virtual IObservable <bool> Close(IReactiveViewModel viewModel) { IViewFor currentView = this.frame.Content as IViewFor; if (currentView == null) { this.Log().Info("Frame has no page. Ignore close for viewmodel {0}.", viewModel); return(Observable.Return(false)); } if (currentView.ViewModel != viewModel) { this.Log().Info("The current page does not correspond to the closing viewmodel. Ignore close for viewmodel {0}.", viewModel); return(Observable.Return(false)); } if (!frame.CanGoBack) { this.Log().Info("The frame can not go back. Ignore close for viewmodel {0}.", viewModel); return(Observable.Return(false)); } this.Log().Info("Closing {0}", viewModel); this.frame.GoBack(); return(Observable.Return(true)); }
public Task NavigateModalAsync(Type viewModelType) { var vm = _container.Resolve(viewModelType); CurrentPage = ResolveView(vm as INavigatableViewModel); return(_navigationFacade.PushModalAsync(CurrentPage)); }
public IObservable <bool> Close(IReactiveViewModel viewModel) { var topViewController = this.MasterNavigationController.TopViewController; if (topViewController == null) { this.Log().Info("No topmost view controller found. Ignore close for viewmodel {0}.", viewModel); return(Observable.Return(false)); } IViewFor currentView = topViewController as IViewFor; if (currentView == null) { this.Log().Info("Topmost view controller is not IViewFor. Ignore close for viewmodel {0}.", viewModel); return(Observable.Return(false)); } if (currentView.ViewModel != viewModel) { this.Log().Info("Topmost view controller does not correspond to the closing viewmodel. Ignore close for viewmodel {0}.", viewModel); return(Observable.Return(false)); } this.MasterNavigationController.PopViewControllerAnimated(true); return(Observable.Return(true)); }
public NavigationRoot(IDetailNavigation detailNavigation, IViewFor <NavigationMenuViewModel> menuPage) { InitializeComponent(); NavigationPage.SetHasNavigationBar(this, false); detailNavigation.PushPage <MainViewModel>(resetStack: true, animate: false).Subscribe(); Detail = (NavigationView)detailNavigation.View; Master = (ContentPage)menuPage; menuPage .WhenAnyObservable(x => x.ViewModel.Navigate) .Select(_ => false) .BindTo(this, x => x.IsPresented); Events .DeviceDisplayMainDisplayInfoChanged .Where(x => x.DisplayInfo.Orientation == DisplayOrientation.Landscape && Device.Idiom == TargetIdiom.Tablet) .Subscribe(x => MasterBehavior = MasterBehavior.SplitOnLandscape) .DisposeWith(_masterDetailBindings); // HACK: [rlittlesii: July 04, 2020] This is a hack around a Xamarin.Forms iOS issue. this.WhenAnyValue(x => x.IsPresented) .Where(x => Device.RuntimePlatform == Device.iOS) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => Master.IconImageSource = ImageSource.FromFile("hamburger.png")) .DisposeWith(_masterDetailBindings); ViewModel = new NavigationRootViewModel(); }
public Answer ShowDialog(IViewFor<IDialogViewModel<Answer>> view, IDialogViewModel<Answer> viewModel) { if (view == null) { throw new ArgumentNullException("view"); } if (viewModel == null) { throw new ArgumentNullException("viewModel"); } view.ViewModel = viewModel; var dialog = view as Window; if (dialog == null) { throw new InvalidOperationException("View must derive from System.Windows.Window."); } dialog.Owner = _parent; dialog.ShowDialog(); return viewModel.Response; }
public ViewModelBase ResolveViewModel(IViewFor viewFor, IEnumerable <object> parameters = null) { var paramList = parameters?.ToList(); switch (viewFor) { case DashboardPage _: return(new DashboardViewModel( _navigationService.Value, _pushNotificationService.Value, _userInteractionService.Value)); case AuthPage _: return(new AuthViewModel( _authService.Value, _userInteractionService.Value, _schedulerService.Value)); case CloudMessagingPage _: return(new CloudMessagingViewModel( _pushNotificationService.Value, _userInteractionService.Value)); case RemoteConfigPage _: return(new RemoteConfigViewModel( _userInteractionService.Value, _firebaseRemoteConfig.Value)); case StoragePage _: return(new StorageViewModel( _userInteractionService.Value, _firebaseStorage.Value)); } throw new ArgumentException($"Couldn't resolve corresponding viewmodel for IViewFor: {viewFor.GetType()}"); }
private static IDisposable HandleViewModelOnViewLoaded(IViewFor view, IObservable <bool> viewEvents) { var vmDisposable = new SerialDisposable(); var viewVmDisposable = new SerialDisposable(); return(new CompositeDisposable( viewEvents.Subscribe(loaded => { if (loaded) { _logger.LogInformation($"Binding {view.ViewModel?.GetType().ToString() ?? "null"} and {view}"); viewVmDisposable.Disposable = view.WhenAnyValue(x => x.ViewModel) .Select(x => x as IViewAware) .Subscribe(x => { // NB: We need to make sure to respect ordering so that the cleanup happens before we execute ViewLoaded again vmDisposable.Disposable = Disposable.Empty; if (x != null) { vmDisposable.Disposable = x.View.ViewLoaded(); } }); } else { viewVmDisposable.Disposable = Disposable.Empty; vmDisposable.Disposable = Disposable.Empty; } }), vmDisposable, viewVmDisposable)); }
/// <summary> /// WhenLoaded allows you to register a Func to be called OnViewLoaded. /// </summary> /// <param name="item">Object that supports loading.</param> /// <param name="block"> /// The method to be called when the corresponding View is loaded. /// It returns a list of Disposables that will be cleaned up when the View is unloaded. /// </param> /// <param name="view"> /// The IViewFor will ordinarily also host the View Model, but in the event it is not, /// a class implementing <see cref="IViewFor<T>" /> can be supplied here. /// </param> /// <returns>A Disposable that cleans up this registration.</returns> public static IDisposable WhenLoaded <T>(this IViewFor <T> item, Func <IEnumerable <IDisposable> > block, IViewFor <T> view) where T : class { if (item == null) { throw new ArgumentNullException(nameof(item)); } var loadedFetcher = _loadedFetcherCache.Get(item.GetType()); if (loadedFetcher == null) { throw new ArgumentException($"Don't know how to detect when {item.GetType().FullName} is loaded/unloaded, you may need to implement {nameof(ILoadedForViewFetcher)}"); } var viewEvents = loadedFetcher.GetLoadedForView(item); var vmDisposable = Disposable.Empty; if ((view ?? item) is IViewFor v) { vmDisposable = HandleViewModelOnViewLoaded(v, viewEvents); } var viewDisposable = typeof(IActivate).IsAssignableFrom(typeof(T)) ? HandleViewOnActivatedAndLoaded((view ?? item), block, viewEvents) : HandleViewOnLoaded(block, viewEvents); return(new CompositeDisposable(vmDisposable, viewDisposable)); }
private void ShowWindowDialog_Closed(object a_sender, EventArgs a_e) { Window window = (Window)a_sender; IWindowViewModel viewModel = (IWindowViewModel)window.DataContext; viewModel.WindowClosed(); viewModel.WindowView = null; window.Closing -= ShowWindowDialog_Closing; window.Closed -= ShowWindowDialog_Closed; Action closeAction = window.Tag as Action; if (closeAction != null) { closeAction(); window.Tag = null; } // Remove the VM. IViewFor viewFor = window as IViewFor; if (viewFor != null) { viewFor.ViewModel = null; } }
public static IDisposable WhenViewModelAnyValue(this IViewFor view, Action <CompositeDisposable> block) { return(view.WhenActivated(disposable => { view.WhenAnyValue(x => x.ViewModel).Where(x => x != null).Subscribe(_ => block.Invoke(disposable)).DisposeWith(disposable); })); }
private IControl StringProperty(object infoFor, PropertyInfo info, IViewFor view, CompositeDisposable disp) { TextBox input = new TextBox { IsReadOnly = !info.CanWrite, }; if (info.CanRead) { input.Text = info.GetValue(infoFor)?.ToString(); } else { input.Text = "<Undefined>"; } if (info.CanWrite) { input .GetObservable(TextBox.TextProperty) .Subscribe(s => { if (!string.IsNullOrWhiteSpace(s) && s != info.GetValue(infoFor)?.ToString()) { info.SetValue(infoFor, s); } }) .DisposeWith(disp); } return(InsertIntoContainer(input, infoFor, info, view, disp)); }
static IDisposable handleViewModelActivation(IViewFor view, IObservable <bool> activation) { var vmDisposable = new SerialDisposable(); var viewVmDisposable = new SerialDisposable(); return(new CompositeDisposable( // Activation activation.Subscribe(activated => { if (activated) { viewVmDisposable.Disposable = view.WhenAnyValue(x => x.ViewModel) .Select(x => x as ISupportsActivation) .Subscribe(x => { // NB: We need to make sure to respect ordering so that the cleanup // happens before we activate again vmDisposable.Disposable = Disposable.Empty; if (x != null) { vmDisposable.Disposable = x.Activator.Activate(); } }); } else { viewVmDisposable.Disposable = Disposable.Empty; vmDisposable.Disposable = Disposable.Empty; } }), vmDisposable, viewVmDisposable)); }
public Task NavigateToMainPage(INavigatableViewModel viewModel) { CurrentView = _viewFactory.ResolveView(viewModel); _loggingService.Info($"Navigating to MainPage: {CurrentView}"); return(_navigationFacade.NavigateToMainPage(CurrentView)); }
public Task NavigateModalAsync(INavigatableViewModel viewModel) { CurrentView = _viewFactory.ResolveView(viewModel); _loggingService.Info($"Opened Modal page: {CurrentView}"); return(_navigationFacade.PushModalAsync(CurrentView)); }
static void SetupCaliburnMicro <T>(T viewModel, IViewFor resolvedView) { var dependencyObject = (DependencyObject)resolvedView; dependencyObject.SetValue(View.IsGeneratedProperty, true); ViewModelBinder.Bind(viewModel, dependencyObject, null); Action.SetTargetWithoutContext(dependencyObject, viewModel); }
public static IDisposable WhenActivated(this IViewFor This, Action <Action <IDisposable> > block) { return(This.WhenActivated(() => { var ret = new List <IDisposable>(); block(ret.Add); return ret; })); }
public static IObservable <TRet> WhenAnyVM <TViewModel, TTarget, TRet>(this IViewFor <TViewModel> This, Expression <Func <TViewModel, TTarget> > propName, Func <IObservedChange <TViewModel, TTarget>, TRet> selector) where TViewModel : class, IReactiveNotifyPropertyChanged { var depObj = This as DependencyObject; return(depObj.WhenAnyDP <DependencyObject, TViewModel, TViewModel>("ViewModel", x => x.Value) .Select(x => x.WhenAny(propName, selector)).Switch()); }
public void Transition(IViewFor fromView, IViewFor toView) { var fromViewController = (UIViewController)fromView; var fromViewModel = (IBaseViewModel)fromView.ViewModel; var toViewController = (UIViewController)toView; var toViewModel = (IBaseViewModel)toView.ViewModel; fromViewController.BeginInvokeOnMainThread(() => DoTransition(fromViewController, fromViewModel, toViewController, toViewModel)); }
static MetroWindow CreateWindow <T>(IViewFor resolvedView) where T : class, IScreenViewModel { var window = new MetroWindow { Content = resolvedView }; window.SetBinding(Window.TitleProperty, new Binding("DisplayName")); return(window); }
/// <summary> /// WhenLoaded allows you to register a Func to be called OnViewLoaded. /// </summary> /// <param name="item">Object that supports viewEvents.</param> /// <param name="block"> /// The method to be called when the corresponding View is loaded. /// It returns a list of Disposables that will be cleaned up when the View is unloaded. /// </param> /// <returns>A Disposable that cleans up this registration.</returns> public static IDisposable WhenLoaded <T>(this IViewFor <T> item, Func <IEnumerable <IDisposable> > block) where T : class { if (item == null) { throw new ArgumentNullException(nameof(item)); } return(item.WhenLoaded(block, null)); }
/// <summary> /// Adds a <see cref="IViewFor"/> to the navigation stack. /// </summary> /// <param name="view">The view to add to the navigation stack.</param> /// <param name="resetStack">Defines if we should reset the navigation stack.</param> public void Push(IViewFor view, bool resetStack = false) { if (resetStack) { _navigationStack.Clear(); } _navigationStack.Add(view); }
/// <summary> /// Initializes a new instance of the <see cref="RoutedControlHost"/> class. /// </summary> public RoutedControlHost() { InitializeComponent(); _disposables.Add(this.WhenAny(x => x.DefaultContent, x => x.Value).Subscribe(x => { if (x != null && Controls.Count == 0) { Controls.Add(InitView(x)); components.Add(DefaultContent); } })); ViewContractObservable = Observable <string> .Default; var vmAndContract = this.WhenAnyObservable(x => x.Router.CurrentViewModel) .CombineLatest( this.WhenAnyObservable(x => x.ViewContractObservable), (vm, contract) => new { ViewModel = vm, Contract = contract }); Control viewLastAdded = null; _disposables.Add(vmAndContract.Subscribe( x => { // clear all hosted controls (view or default content) SuspendLayout(); Controls.Clear(); if (viewLastAdded != null) { viewLastAdded.Dispose(); } if (x.ViewModel == null) { if (DefaultContent != null) { InitView(DefaultContent); Controls.Add(DefaultContent); } ResumeLayout(); return; } IViewLocator viewLocator = ViewLocator ?? ReactiveUI.ViewLocator.Current; IViewFor view = viewLocator.ResolveView(x.ViewModel, x.Contract); view.ViewModel = x.ViewModel; viewLastAdded = InitView((Control)view); Controls.Add(viewLastAdded); ResumeLayout(); }, RxApp.DefaultExceptionHandler.OnNext)); }
public Task NavigateModalAsync(Type viewModelType) { var vm = _viewModelFactory.GetViewModel(viewModelType); CurrentView = _viewFactory.ResolveView(vm); _loggingService.Info($"Opened Modal page: {CurrentView}"); return(_navigationFacade.PushModalAsync(CurrentView)); }
public Task NavigateToMainPage(Type viewModelType) { var vm = _viewModelFactory.GetMainViewModel(viewModelType, _platformFacade.RuntimePlatform); CurrentView = _viewFactory.ResolveView(vm); _loggingService.Info($"Navigating to MainPage: {CurrentView}"); return(_navigationFacade.NavigateToMainPage(CurrentView)); }
/// <summary> /// WhenLoaded allows you to register a Func to be called OnViewLoaded. /// </summary> /// <param name="item">Object that supports loading.</param> /// <param name="block"> /// The method to be called when the corresponding View is loaded. /// The Action parameter (usually called 'd') allows /// you to register Disposables to be cleaned up when the View is /// unloaded (i.e. "d(someObservable.Subscribe());"). /// </param> /// <param name="view"> /// The IViewFor will ordinarily also host the View Model, but in the event it is not, /// a class implementing <see cref="IViewFor<T>" /> can be supplied here. /// </param> /// <returns>A Disposable that cleans up this registration.</returns> public static IDisposable WhenLoaded <T>(this IViewFor <T> item, Action <Action <IDisposable> > block, IViewFor <T> view) where T : class { return(item.WhenLoaded( () => { var ret = new List <IDisposable>(); block(ret.Add); return ret; }, view)); }
/// <summary> /// WhenLoaded allows you to register a Func to be called OnViewLoaded. /// </summary> /// <param name="item">Object that supports loading.</param> /// <param name="block"> /// The method to be called when the corresponding View is loaded. /// The Action parameter (usually called 'd') allows /// you to register Disposables to be cleaned up when the View is /// unloaded (i.e. "d(someObservable.Subscribe());"). /// The Action parameter (usually called 'disposables') allows /// you to collate all disposables that should be cleaned up during unloading. /// </param> /// <param name="view"> /// The IViewFor will ordinarily also host the View Model, but in the event it is not, /// a class implementing <see cref="IViewFor<T>" /> can be supplied here. /// </param> /// <returns>A Disposable that cleans up this registration.</returns> public static IDisposable WhenLoaded <T>(this IViewFor <T> item, Action <CompositeDisposable> block, IViewFor <T> view = null) where T : class { return(item.WhenLoaded( () => { var d = new CompositeDisposable(); block(d); return new[] { d }; }, view)); }
public static EntryElement Bind <T>(this EntryElement entryElement, IViewFor <T> view, System.Linq.Expressions.Expression <Func <T, string> > bindMember) where T : ReactiveObject { // view.Bind(view.ViewModel, // var bindDelegate = bindMember.Compile(); // entryElement.Changed += (sender, e) => bindDelegate(; // viewModel.WhenAnyValue(bindMember).Subscribe(x => entryElement.Value = x); return(entryElement); }
public IControl GetControl(object infoFor, PropertyInfo info, IViewFor view, CompositeDisposable disp) { if (info == null) { return(null); } if (factoryDict.ContainsKey(info.PropertyType)) { return(factoryDict[info.PropertyType](infoFor, info, view, disp)); } return(DefaultProperty(infoFor, info, view, disp)); }
public void ResolveViewTest() { var dependencyResolver = MockRepository.GenerateStub <IDependencyResolver>(); var viewLocator = new ViewLocatorEx(dependencyResolver); dependencyResolver.Stub(x => x.GetService(typeof(IViewFor <ITestViewModel>))).Return(new TestView()); IViewFor view = viewLocator.ResolveView(new TestViewModel()); dependencyResolver.AssertWasCalled(x => x.GetService(typeof(IViewFor <ITestViewModel>))); Assert.That(view, Is.InstanceOf <TestView>()); }
public Task NavigateToMainPage(IViewFor page) { if (Device.RuntimePlatform == Device.Android) { App.Current.MainPage = page as Page; } else if (Device.RuntimePlatform == Device.iOS) { App.Current.MainPage = new CustomNavigationPage(page as Page); } return(Task.CompletedTask); }
public static IDisposable WhenActivated( this IActivatable @this, Action <CompositeDisposable> disposables, IViewFor view = null) { return(@this.WhenActivated(() => { var d = new CompositeDisposable(); disposables(d); return new[] { d }; }, view)); }
public static IDisposable WhenActivated( this IActivatable @this, Action<CompositeDisposable> disposables, IViewFor view = null) { Ensure.ArgumentNotNull(@this, nameof(@this)); return @this .WhenActivated( () => { var d = new CompositeDisposable(); disposables(d); return new[] { d }; }, view); }
static IDisposable handleViewModelActivation(IViewFor view, Tuple<IObservable<Unit>, IObservable<Unit>> activation) { var vm = view.ViewModel as ISupportsActivation; var disp = new SerialDisposable() {Disposable = (vm != null ? vm.Activator.Activate() : Disposable.Empty)}; var latestVm = Observable.Merge( activation.Item1.Select(_ => view.WhenAnyValue(x => x.ViewModel)), activation.Item2.Select(_ => Observable.Never<object>().StartWith(default(object)))) .Switch() .Select(x => x as ISupportsActivation); return new CompositeDisposable( disp, latestVm.Subscribe(x => disp.Disposable = (x != null ? x.Activator.Activate() : Disposable.Empty))); }
public Tuple<IObservable<Unit>, IObservable<Unit>> GetActivationForView(IViewFor view) { var fe = view as FrameworkElement; if (fe == null) return Tuple.Create(Observable.Empty<Unit>(), Observable.Empty<Unit>()); var viewLoaded = Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(x => fe.Loaded += x, x => fe.Loaded -= x).Select(_ => Unit.Default); var viewHitTestVisible = fe.WhenAnyValue(v => v.IsHitTestVisible); var viewActivated = viewLoaded.Zip(viewHitTestVisible, (l, h) => h) .Where(v => v) .Select(_ => Unit.Default); var viewUnloaded = Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(x => fe.Unloaded += x, x => fe.Unloaded -= x).Select(_ => Unit.Default); return Tuple.Create(viewActivated, viewUnloaded); }
static IDisposable handleViewModelActivation(IViewFor view, IObservable<bool> activation) { var vmDisposable = new SerialDisposable(); var viewVmDisposable = new SerialDisposable(); return new CompositeDisposable( // Activation activation.Subscribe(activated => { if (activated) { viewVmDisposable.Disposable = view.WhenAnyValue(x => x.ViewModel) .Select(x => x as ISupportsActivation) .Subscribe(x => { // NB: We need to make sure to respect ordering so that the cleanup // happens before we activate again vmDisposable.Disposable = Disposable.Empty; if (x != null) { vmDisposable.Disposable = x.Activator.Activate(); } }); } else { viewVmDisposable.Disposable = Disposable.Empty; vmDisposable.Disposable = Disposable.Empty; } }), vmDisposable, viewVmDisposable); }
/// <summary> /// WhenActivated allows you to register a Func to be called when a /// View is Activated. /// </summary> /// <param name="block">The method to be called when the corresponding /// View is activated. The Action parameter (usually called 'd') allows /// you to register Disposables to be cleaned up when the View is /// deactivated (i.e. "d(someObservable.Subscribe());")</param> /// <param name="view">The IActivatable will ordinarily also host the View /// Model, but in the event it is not, a class implementing <see cref="IViewFor" /> /// can be supplied here. /// <returns>A Disposable that deactivates this registration.</returns> public static IDisposable WhenActivated(this IActivatable This, Action<Action<IDisposable>> block, IViewFor view) { return This.WhenActivated(() => { var ret = new List<IDisposable>(); block(ret.Add); return ret; }, view); }
/// <summary> /// WhenActivated allows you to register a Func to be called when a /// View is Activated. /// </summary> /// <param name="block">The method to be called when the corresponding /// View is activated. It returns a list of Disposables that will be /// cleaned up when the View is deactivated.</param> /// <param name="view">The IActivatable will ordinarily also host the View /// Model, but in the event it is not, a class implementing <see cref="IViewFor" /> /// can be supplied here. /// <returns>A Disposable that deactivates this registration.</returns> public static IDisposable WhenActivated(this IActivatable This, Func<IEnumerable<IDisposable>> block, IViewFor view) { var activationFetcher = activationFetcherCache.Get(This.GetType()); if (activationFetcher == null) { var msg = "Don't know how to detect when {0} is activated/deactivated, you may need to implement IActivationForViewFetcher"; throw new ArgumentException(String.Format(msg, This.GetType().FullName)); } var activationEvents = activationFetcher.GetActivationForView(This); var vmDisposable = Disposable.Empty; var v = view ?? This; if (v is IViewFor) { vmDisposable = handleViewModelActivation(v as IViewFor, activationEvents); } var viewDisposable = handleViewActivation(block, activationEvents); return new CompositeDisposable(vmDisposable, viewDisposable); }
public void Transition(IViewFor fromView, IViewFor toView) { Console.WriteLine("Im here!"); }
static IDisposable handleViewModelActivation(IViewFor view, Tuple<IObservable<Unit>, IObservable<Unit>> activation) { var vmDisposable = new SerialDisposable(); return new CompositeDisposable( // Activation activation.Item1 .Select(_ => view.WhenAnyValue(x => x.ViewModel)) .Switch() .Select(x => x as ISupportsActivation) .Subscribe(x => { // NB: We need to make sure to respect ordering so that the cleanup // happens before we activate again vmDisposable.Disposable = Disposable.Empty; if(x != null) { vmDisposable.Disposable = x.Activator.Activate(); } }), // Deactivation activation.Item2.Subscribe(_ => { vmDisposable.Disposable = Disposable.Empty; }), vmDisposable); }
public Tuple<IObservable<Unit>, IObservable<Unit>> GetActivationForView(IViewFor view) { var ca = view as ICanActivate; return Tuple.Create(ca.Activated, ca.Deactivated); }
/// <summary> /// WhenActivated allows you to register a Func to be called when a /// View is Activated. /// </summary> /// <param name="This">Object that supports activation.</param> /// <param name="block">The method to be called when the corresponding /// View is activated. The Action parameter (usually called 'disposables') allows /// you to collate all disposables that should be cleaned up during deactivation.</param> /// <param name="view">The IActivatable will ordinarily also host the View /// Model, but in the event it is not, a class implementing <see cref="IViewFor" /> /// can be supplied here. /// <returns>A Disposable that deactivates this registration.</returns> public static IDisposable WhenActivated(this IActivatable This, Action<CompositeDisposable> block, IViewFor view = null) { return This.WhenActivated(() => { var d = new CompositeDisposable(); block(d); return new[] { d }; }, view); }