private static void AddClosingByRequest <TView>(TView view, LayoutContent layoutDocument) where TView : class, IView { if (!(view.ViewModel is ViewModelBase baseViewModel)) { return; } Observable .FromEventPattern <ViewModelCloseQueryArgs>( x => baseViewModel.CloseQuery += x, x => baseViewModel.CloseQuery -= x) .Subscribe(x => { layoutDocument.Close(); }) .DisposeWith(baseViewModel.Disposables); Observable .FromEventPattern <CancelEventArgs>( x => layoutDocument.Closing += x, x => layoutDocument.Closing -= x) .Subscribe(x => { var vcq = new ViewModelCloseQueryArgs { IsCanceled = false }; baseViewModel.Closing(vcq); if (vcq.IsCanceled) { x.EventArgs.Cancel = true; } }) .DisposeWith(baseViewModel.Disposables); Observable .FromEventPattern( x => layoutDocument.Closed += x, x => layoutDocument.Closed -= x) .Subscribe(_ => baseViewModel.Closed(new ViewModelCloseQueryArgs { IsCanceled = false })) .DisposeWith(baseViewModel.Disposables); }
private static void AddClosingByRequest <TView>(TView view, LayoutDocument layoutDocument) where TView : class, IView { if (view.ViewModel is ViewModelBase baseViewModel) { var v = view.ViewModel as ViewModelBase; var closeQuery = Observable.FromEventPattern <ViewModelCloseQueryArgs>( x => baseViewModel.CloseQuery += x, x => baseViewModel.CloseQuery -= x); var subscription = closeQuery.Subscribe(x => { layoutDocument.Close(); }); layoutDocument.Closing += (s, e) => { ViewModelCloseQueryArgs vcq = new ViewModelCloseQueryArgs { IsCanceled = false }; v.Closing(vcq); if (vcq.IsCanceled) { e.Cancel = true; } }; layoutDocument.Closed += (s, e) => { try { v.Closed(new ViewModelCloseQueryArgs { IsCanceled = false }); } finally { subscription.Dispose(); } }; } }
public Task <TResult> ShowChildWindowView <TResult>(Func <ILifetimeScope, IView> viewFactory, ViewRequest viewRequest = null, UiShowChildWindowOptions options = null) { if (!string.IsNullOrEmpty(viewRequest?.ViewId)) { var metroDialogContainer = Window.Template.FindName("PART_MetroActiveDialogContainer", Window) as Grid; metroDialogContainer = metroDialogContainer ?? Window.Template.FindName("PART_MetroInactiveDialogsContainer", Window) as Grid; if (metroDialogContainer == null) { throw new InvalidOperationException( "The provided child window can not add, there is no container defined."); } var viewOld = metroDialogContainer.Children .Cast <ChildWindowView>() .Select(x => (IView)x.Content) .FirstOrDefault(x => (x.ViewModel as ViewModelBase)?.ViewId == viewRequest.ViewId); if (viewOld != null) { (viewOld.ViewModel as Ui.Wpf.Common.ViewModels.IActivatableViewModel)?.Activate(viewRequest); return(Task.FromResult(default(TResult))); } } var view = viewFactory(Container); if (options != null) { view.Configure(options); } InitializeView(view, viewRequest); (view.ViewModel as Ui.Wpf.Common.ViewModels.IActivatableViewModel)?.Activate(viewRequest); options = options ?? new UiShowChildWindowOptions(); var childWindow = new ChildWindowView(options) { Content = view }; var vm = view.ViewModel as ViewModelBase; if (vm != null) { Observable .FromEventPattern <ViewModelCloseQueryArgs>( x => vm.CloseQuery += x, x => vm.CloseQuery -= x) .Subscribe(x => { if (vm is IResultableViewModel <TResult> model) { childWindow.Close(model.ViewResult); } else { childWindow.Close(); } }) .DisposeWith(vm.Disposables); Observable .FromEventPattern <CancelEventArgs>( x => childWindow.Closing += x, x => childWindow.Closing -= x) .Subscribe(x => { var vcq = new ViewModelCloseQueryArgs { IsCanceled = false }; vm.Closing(vcq); if (vcq.IsCanceled) { x.EventArgs.Cancel = true; } }) .DisposeWith(vm.Disposables); } var disposables = new CompositeDisposable(); view.ViewModel .WhenAnyValue(x => x.Title) .Subscribe(x => childWindow.Title = x) .DisposeWith(disposables); view.ViewModel .WhenAnyValue(x => x.CanClose) .Subscribe(x => childWindow.ShowCloseButton = x) .DisposeWith(disposables); Observable .FromEventPattern <RoutedEventHandler, RoutedEventArgs>( x => childWindow.ClosingFinished += x, x => childWindow.ClosingFinished -= x) .Select(x => (ChildWindow)x.Sender) .Take(1) .Subscribe(x => { disposables.Dispose(); vm?.Closed(new ViewModelCloseQueryArgs()); x.Content = null; }); return(Window.ShowChildWindowAsync <TResult>( childWindow, options.OverlayFillBehavior )); }