Beispiel #1
0
 private void OpenScreen(ScreenConductor conductor, IScreenBase screen)
 {
     try {
         conductor.OpenScreen(ScreenFactory.For(screen));
     } catch (ScreenLifecycleException) {
     }
 }
Beispiel #2
0
 private void ShowDialogAndExpectException(IScreenBase screen)
 {
     AssertHelper.Throws <ScreenLifecycleException>(
         () => ShowDialog(screen),
         unwrapTargetInvocationException: true
         );
 }
Beispiel #3
0
        private DialogScreenResult ShowModal(IScreenFactory <IScreenBase> screenFactory)
        {
            _modal = true;

            DialogLifecycle dialogLifecycle = null;

            try {
                _screen = screenFactory.Create(
                    _aggregator,
                    s => {
                    dialogLifecycle = new DialogLifecycle(s);
                    s.Children.Add(dialogLifecycle);
                }
                    );

                Initialize();

                try {
                    _windowService.ShowWindow(_window, modal: true);
                } catch (Exception ex) {
                    // If an exception is thrown in the UI code of the dialog window (e.g. in
                    // a command handler or on a Dispatcher action), ShowDialog rethrows this
                    // exception but leaves the Window open and visible.
                    if (!ex.IsCritical() && _window.IsVisible)
                    {
                        CloseWindowImmediatately();
                    }

                    // It's possible that 'HandleClose' or 'HandleWindowClosed' was already executed
                    // but 'ShowDialog' still threw an exception. In that case we have to check the
                    // current state of the screen to prevent invalid state transitions.
                    // TODO: Write a Unit Test when it's known how to reproduce it!
                    CloseScreen(checkState: true);

                    throw;
                }

                if (_lastWindowHandlerException != null)
                {
                    throw _lastWindowHandlerException;
                }

                return(dialogLifecycle.ScreenResult ?? new DialogScreenResult(false));
            } finally {
                Disconnect();

                if (_screen != null)
                {
                    _screen
                    .Children
                    .Remove(dialogLifecycle);
                }

                if (_window.Owner != null)
                {
                    // Fix for http://stackoverflow.com/questions/3144004/wpf-app-loses-completely-focus-on-window-close
                    _window.Owner.Activate();
                }
            }
        }
 private static DialogLifecycle TryGetDialogLifecycle(IScreenBase forScreen)
 {
     return(ScreenTreeHelper
            .GetAncestorsOf(forScreen, includeSelf: true)
            .SelectMany(x => x.Children.OfType <DialogLifecycle>())
            .FirstOrDefault());
 }
Beispiel #5
0
        private void DeactivateScreen(IScreenBase screen)
        {
            if (screen == null || Lifecycle.State != LifecycleState.Activated)
            {
                return;
            }

            // 'ScreenConductor.RequestClose' removes the screen if the 'RequestClose'
            // event throws an exception and sets the 'ActiveScreen' to the last active
            // screen. In this case the currently active screen may already be in an
            // error state in which case we must not call 'Deactivate'.
            if (!Screens.Contains(screen))
            {
                return;
            }

            try {
                GetLifecycleOps(screen).Deactivate();
            } catch (ScreenLifecycleException) {
                _activatedScreensHistory.Remove(screen);

                // 'Remove' may throw an arbitrary exception
                _screens.Remove(screen);
                throw;
            }
        }
        private void AddScreen(IScreenBase screen)
        {
            object view = CreateView(forScreen: screen);

            _screenViews.Add(screen, view);
            OnViewAdded(view);
        }
        private void RemoveScreen(IScreenBase screen)
        {
            object view = GetViewForScreen(screen);

            _screenViews.Remove(screen);
            OnViewRemoved(view);
        }
        public virtual bool ShowOpenFileDialog(
            IScreenBase parent,
            out string fileName,
            string filter                     = null,
            string initialDirectory           = null,
            IEnumerable <string> customPlaces = null
            )
        {
            Window         ownerWin = GetAssociatedWindow(parent);
            OpenFileDialog ofd      = new OpenFileDialog();

            if (filter != null)
            {
                ofd.Filter = filter;
            }

            if (initialDirectory != null)
            {
                ofd.InitialDirectory = initialDirectory;
            }

            if (customPlaces != null)
            {
                foreach (string customPlace in customPlaces)
                {
                    ofd.CustomPlaces.Add(new FileDialogCustomPlace(customPlace));
                }
            }

            var result = ofd.ShowDialog(ownerWin);

            fileName = ofd.FileName;
            return(result.Value);
        }
Beispiel #9
0
 private void CloseScreen(ScreenConductor conductor, IScreenBase screen, bool skipRequestClose)
 {
     try {
         conductor.CloseScreen(screen, skipRequestClose);
     } catch (ScreenLifecycleException) {
     }
 }
Beispiel #10
0
        private void Show(IScreenFactory <IScreenBase> screenFactory)
        {
            _modal = false;

            _screen = screenFactory.Create(_aggregator);
            Initialize();
            _windowService.ShowWindow(_window, modal: false);
        }
 public ScreenLifecycleOperations(
     EventAggregator aggregator,
     IScreenBase target
     )
 {
     _aggregator = aggregator;
     _target     = target;
 }
Beispiel #12
0
 private void UpdateHistory(IScreenBase mostRecentlyActivatedScreen)
 {
     if (mostRecentlyActivatedScreen != null)
     {
         _activatedScreensHistory.Remove(mostRecentlyActivatedScreen);
         _activatedScreensHistory.Add(mostRecentlyActivatedScreen);
     }
 }
Beispiel #13
0
 internal ScreenOpenedEventArgs(
     ScreenConductor conductor,
     IScreenBase screen,
     bool wasAlreadyOpen
     )
     : base(conductor, screen)
 {
     WasAlreadyOpen = wasAlreadyOpen;
 }
Beispiel #14
0
        bool IDialogService.ShowFolderBrowseDialog(IScreenBase parent, out string selectedPath, string message, Environment.SpecialFolder?specialFolder)
        {
            var invocation = new DialogServiceInvocation(DialogServiceMethod.ShowOpenFileDialog);

            invocation.Message.SetValue(message);
            invocation.Parent.SetValue(parent);

            return(DequeueResponder().ProcessFolderDialogInvocation(invocation, out selectedPath));
        }
Beispiel #15
0
        public void ScreenFactoriesForConcreteScree_CanBeAssignedToScreenBaseFactoryVariable()
        {
            IScreenFactory <TestScreen>  concreteFactory = ScreenFactory.For <TestScreen>();
            IScreenFactory <IScreenBase> factory         = concreteFactory;

            IScreenBase screen = factory.Create(Aggregator);

            Assert.IsInstanceOfType(screen, typeof(TestScreen));
        }
        public static IEnumerable <IScreenBase> GetChildrenOf(IScreenBase screen, bool includeSelf = false)
        {
            IEnumerable <IScreenBase> children = screen
                                                 .Children
                                                 .OfType <IScreenBase>();

            return(includeSelf ?
                   new[] { screen }.Union(children) :
                   children);
        }
Beispiel #17
0
        bool IDialogService.ShowOpenFileDialog(IScreenBase parent, out string fileName, string filter, string initialDirectory, IEnumerable <string> customPlaces)
        {
            var invocation = new DialogServiceInvocation(DialogServiceMethod.ShowOpenFileDialog);

            invocation.Filter.SetValue(filter);
            invocation.InitialDirectory.SetValue(initialDirectory);
            invocation.Parent.SetValue(parent);

            return(DequeueResponder().ProcessFileDialogInvocation(invocation, out fileName));
        }
        protected override void AddCore(T item)
        {
            IScreenBase s = item as IScreenBase;

            if (s != null && s.Parent == null)
            {
                s.Parent = _parent;
            }

            base.AddCore(item);
        }
Beispiel #19
0
        internal ConductorEventArgs(
            ScreenConductor conductor,
            IScreenBase screen
            )
        {
            Check.NotNull(conductor, nameof(conductor));
            Check.NotNull(screen, nameof(screen));

            Conductor = conductor;
            Screen    = screen;
        }
Beispiel #20
0
        public TestScreenResult ShowDialog <TScreen>(
            IScreenFactory <TScreen> screen
            ) where TScreen : IScreenBase
        {
            IScreenBase s         = screen.Create(_aggregator);
            var         lifecycle = new DialogLifecycle(s);

            s.Children.Add(lifecycle);
            s.Children.Add(new ScreenCloseHandler(_ => { })); // TODO: Remove code duplication between here and responder
            return(new TestScreenResult(lifecycle));
        }
        public static DialogLifecycle GetDialogLifecycle(IScreenBase forScreen)
        {
            var lifecycle = TryGetDialogLifecycle(forScreen);

            if (lifecycle == null)
            {
                throw new ArgumentException(ExceptionTexts.ScreenIsNoDialog);
            }

            return(lifecycle);
        }
        public static IEnumerable <IScreenBase> GetAncestorsOf(IScreenBase screen, bool includeSelf = false)
        {
            if (!includeSelf)
            {
                screen = screen.Parent;
            }

            for (IScreenBase s = screen; s != null; s = s.Parent)
            {
                yield return(s);
            }
        }
        protected override bool RemoveCore(T item)
        {
            bool result = base.RemoveCore(item);

            IScreenBase s = item as IScreenBase;

            if (s != null && s.Parent == _parent)
            {
                s.Parent = null;
            }

            return(result);
        }
        internal static TChild GetChild <TChild>(IScreenBase screen)
        {
            TChild child = screen
                           .Children
                           .OfType <TChild>()
                           .SingleOrDefault();

            if (child == null)
            {
                throw new ArgumentException();
            }

            return(child);
        }
Beispiel #25
0
        public void OpenScreen <TScreen>(IScreenFactory <TScreen> factory)
            where TScreen : class, IScreenBase
        {
            ScreenCreationBehavior creationBehavior  = GetCreationBehavior(factory);
            IScreenBase            alreadyOpenScreen = null;

            switch (creationBehavior)
            {
            case ScreenCreationBehavior.MultipleInstances:
                break;

            case ScreenCreationBehavior.SingleInstance:
                alreadyOpenScreen = _screens
                                    .SingleOrDefault(x => x.GetType() == factory.ScreenType);
                break;

            case ScreenCreationBehavior.UseScreenLocation:
                alreadyOpenScreen = Screens
                                    .FirstOrDefault(x => factory.CreatesScreensEquivalentTo(x));
                break;
            }

            bool wasAlreadyOpen = alreadyOpenScreen != null;

            IScreenBase s;

            if (wasAlreadyOpen)
            {
                s = alreadyOpenScreen;
            }
            else
            {
                // If the constructor or Initialize handler of the screen throws an
                // exception we exit here and 'ActiveScreen' is not changed. The screen
                // itself makes sure that is consistently closed in case of an exception.
                s = _screens.AddScreen(factory);
                s.Children
                .Add(new ScreenCloseHandler(requestClose => CloseScreen(s, requestClose)));
            }

            // Activate does handle exceptions correctly and rethrows them, so we skip
            // the publishing of the 'ScreenOpenedEvent'.
            ActiveScreen = s;

            _eventAggregator.Publish(
                ScreenOpenedEvent,
                new ScreenOpenedEventArgs(this, s, wasAlreadyOpen)
                );
        }
Beispiel #26
0
        public ScreenLifecycle(EventAggregator aggregator, IScreenBase parent)
        {
            _parent = parent;
            _subscriptionManager = new EventSubscriptionManager(aggregator);
            _sm = new LifecycleStateMachine(_parent);

            DefineTransitions();

            _subscriptionManager.Subscribe(b =>
                                           b.AddSubscription(_sm)
                                           );

            RegisterHandlerForINeedsInitializationImplementations();

            _parent.Children.Add(this);
        }
        /// <remarks>
        ///   Note to inheritors: This method does not call <see
        ///   cref="Show(Window,IScreenFactory{IScreenBase},bool)"/>.
        /// </remarks>
        public virtual void Show(
            IScreenFactory <IScreenBase> screen,
            IScreenBase parent = null,
            string title       = null
            )
        {
            Window ownerWin = GetAssociatedWindow(parent);
            Window window   = _windowService.CreateWindow(ownerWin, title, false);

            WindowLifecycle.Show(
                _aggregator,
                _windowService,
                window,
                screen,
                modal: false
                );
        }
        /// <remarks>
        ///   Note to inheritors: This method does not call <see
        ///   cref="Show(Window, IScreenFactory{IScreenBase}, bool)"/>.
        /// </remarks>
        public virtual DialogScreenResult ShowDialog(
            IScreenFactory <IScreenBase> screen,
            IScreenBase parent = null,
            string title       = null
            )
        {
            Window ownerWin = GetAssociatedWindow(parent);
            Window window   = _windowService.CreateWindow(ownerWin, title, true);

            return(WindowLifecycle.Show(
                       _aggregator,
                       _windowService,
                       window,
                       screen,
                       modal: true
                       ));
        }
Beispiel #29
0
        private void ActivateScreen(IScreenBase screen)
        {
            if (screen == null || Lifecycle.State != LifecycleState.Activated)
            {
                return;
            }

            try {
                GetLifecycleOps(screen).Activate();
            } catch (ScreenLifecycleException) {
                _activatedScreensHistory.Remove(screen);

                // 'Remove' may throw an arbitrary exception
                _screens.Remove(screen);
                throw;
            }
        }
Beispiel #30
0
        private void AddEventHandlerFor <TArgs>(
            ScreenLifecycleEvent <TArgs> @event,
            IScreenBase screen,
            Action <ScreenLifecycleEvent <TArgs>, TArgs> handlerAction
            ) where TArgs : ScreenEventArgs
        {
            var subscription = new HierarchicalEventSubscription <IScreenBase, TArgs>(
                @event,
                args => handlerAction(@event, args),
                ExecutionOrder.Default,
                null,
                screen
                );

            _sm.Subscribe(b =>
                          b.AddSubscription(subscription)
                          );
        }