Beispiel #1
0
        /// <summary>
        /// Called by View whenever its current View.Model changes. Will locate and instantiate the correct view, and set it as the target's Content
        /// </summary>
        /// <param name="targetLocation">Thing which View.Model was changed on. Will have its Content set</param>
        /// <param name="oldValue">Previous value of View.Model</param>
        /// <param name="newValue">New value of View.Model</param>
        public virtual void OnModelChanged(DependencyObject targetLocation, object oldValue, object newValue)
        {
            if (oldValue == newValue)
            {
                return;
            }

            if (newValue != null)
            {
                logger.Info("View.Model changed for {0} from {1} to {2}", targetLocation, oldValue, newValue);
                var view = this.CreateAndBindViewForModelIfNecessary(newValue);
                if (view is Window)
                {
                    var e = new StyletInvalidViewTypeException(String.Format("s:View.Model=\"...\" tried to show a View of type '{0}', but that View derives from the Window class. " +
                                                                             "Make sure any Views you display using s:View.Model=\"...\" do not derive from Window (use UserControl or similar)", view.GetType().Name));
                    logger.Error(e);
                    throw e;
                }
                View.SetContentProperty(targetLocation, view);
            }
            else
            {
                logger.Info("View.Model cleared for {0}, from {1}", targetLocation, oldValue);
                View.SetContentProperty(targetLocation, null);
            }
        }
        /// <summary>
        /// Given a ViewModel, create its View, ensure that it's a Window, and set it up
        /// </summary>
        /// <param name="viewModel">ViewModel to create the window for</param>
        /// <param name="isDialog">True if the window will be used as a dialog</param>
        /// <param name="ownerViewModel">Optionally the ViewModel which owns the view which should own this window</param>
        /// <returns>Window which was created and set up</returns>
        protected virtual Window CreateWindow(object viewModel, bool isDialog, IViewAware ownerViewModel)
        {
            var view   = this.viewManager.CreateAndBindViewForModelIfNecessary(viewModel);
            var window = view as Window;

            if (window == null)
            {
                var e = new StyletInvalidViewTypeException(String.Format("WindowManager.ShowWindow or .ShowDialog tried to show a View of type '{0}', but that View doesn't derive from the Window class. " +
                                                                         "Make sure any Views you display using WindowManager.ShowWindow or .ShowDialog derive from Window (not UserControl, etc)",
                                                                         view == null ? "(null)" : view.GetType().Name));
                logger.Error(e);
                throw e;
            }

            // Only set this it hasn't been set / bound to anything
            var haveDisplayName = viewModel as IHaveDisplayName;

            if (haveDisplayName != null && (String.IsNullOrEmpty(window.Title) || window.Title == view.GetType().Name) && BindingOperations.GetBindingBase(window, Window.TitleProperty) == null)
            {
                var binding = new Binding("DisplayName")
                {
                    Mode = BindingMode.TwoWay
                };
                window.SetBinding(Window.TitleProperty, binding);
            }

            if (ownerViewModel?.View is Window explicitOwner)
            {
                window.Owner = explicitOwner;
            }
            else if (isDialog)
            {
                var owner = this.InferOwnerOf(window);
                if (owner != null)
                {
                    // We can end up in a really weird situation if they try and display more than one dialog as the application's closing
                    // Basically the MainWindow's no long active, so the second dialog chooses the first dialog as its owner... But the first dialog
                    // hasn't yet been shown, so we get an exception ("cannot set owner property to a Window which has not been previously shown").
                    try
                    {
                        window.Owner = owner;
                    }
                    catch (InvalidOperationException e)
                    {
                        logger.Error(e, "This can occur when the application is closing down");
                    }
                }
            }

            if (isDialog)
            {
                logger.Info("Displaying ViewModel {0} with View {1} as a Dialog", viewModel, window);
            }
            else
            {
                logger.Info("Displaying ViewModel {0} with View {1} as a Window", viewModel, window);
            }

            // If and only if they haven't tried to position the window themselves...
            // Has to be done after we're attempted to set the owner
            if (window.WindowStartupLocation == WindowStartupLocation.Manual && Double.IsNaN(window.Top) && Double.IsNaN(window.Left) &&
                BindingOperations.GetBinding(window, Window.TopProperty) == null && BindingOperations.GetBinding(window, Window.LeftProperty) == null)
            {
                window.WindowStartupLocation = window.Owner == null ? WindowStartupLocation.CenterScreen : WindowStartupLocation.CenterOwner;
            }

            // This gets itself retained by the window, by registering events
            // ReSharper disable once ObjectCreationAsStatement
            new WindowConductor(window, viewModel);

            return(window);
        }
Beispiel #3
0
        /// <summary>
        /// Called by View whenever its current View.Model changes. Will locate and instantiate the correct view, and set it as the target's Content
        /// </summary>
        /// <param name="targetLocation">Thing which View.Model was changed on. Will have its Content set</param>
        /// <param name="oldValue">Previous value of View.Model</param>
        /// <param name="newValue">New value of View.Model</param>
        public virtual void OnModelChanged(DependencyObject targetLocation, object oldValue, object newValue)
        {
            if (oldValue == newValue)
                return;

            if (newValue != null)
            {
                logger.Info("View.Model changed for {0} from {1} to {2}", targetLocation, oldValue, newValue);
                var view = this.CreateAndBindViewForModelIfNecessary(newValue);
                if (view is Window)
                {
                    var e = new StyletInvalidViewTypeException(String.Format("s:View.Model=\"...\" tried to show a View of type '{0}', but that View derives from the Window class. " +
                    "Make sure any Views you display using s:View.Model=\"...\" do not derive from Window (use UserControl or similar)", view.GetType().Name));
                    logger.Error(e);
                    throw e;
                }
                View.SetContentProperty(targetLocation, view);
            }
            else
            {
                logger.Info("View.Model cleared for {0}, from {1}", targetLocation, oldValue);
                View.SetContentProperty(targetLocation, null);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Given a ViewModel, create its View, ensure that it's a Window, and set it up
        /// </summary>
        /// <param name="viewModel">ViewModel to create the window for</param>
        /// <param name="isDialog">True if the window will be used as a dialog</param>
        /// <returns>Window which was created and set up</returns>
        protected virtual Window CreateWindow(object viewModel, bool isDialog)
        {
            var view = this.viewManager.CreateAndBindViewForModelIfNecessary(viewModel);
            var window = view as Window;
            if (window == null)
            {
                var e = new StyletInvalidViewTypeException(String.Format("WindowManager.ShowWindow or .ShowDialog tried to show a View of type '{0}', but that View doesn't derive from the Window class. " +
                    "Make sure any Views you display using WindowManager.ShowWindow or .ShowDialog derive from Window (not UserControl, etc)",
                    view == null ? "(null)" : view.GetType().Name));
                logger.Error(e);
                throw e;
            }

            // Only set this it hasn't been set / bound to anything
            var haveDisplayName = viewModel as IHaveDisplayName;
            if (haveDisplayName != null && (String.IsNullOrEmpty(window.Title) || window.Title == view.GetType().Name) && BindingOperations.GetBindingBase(window, Window.TitleProperty) == null)
            {
                var binding = new Binding("DisplayName") { Mode = BindingMode.TwoWay };
                window.SetBinding(Window.TitleProperty, binding);
            }

            if (isDialog)
            {
                var owner = this.InferOwnerOf(window);
                if (owner != null)
                {
                    // We can end up in a really weird situation if they try and display more than one dialog as the application's closing
                    // Basically the MainWindow's no long active, so the second dialog chooses the first dialog as its owner... But the first dialog
                    // hasn't yet been shown, so we get an exception ("cannot set owner property to a Window which has not been previously shown").
                    try
                    {
                        window.Owner = owner;
                    }
                    catch (InvalidOperationException e)
                    {
                        logger.Error(e, "This can occur when the application is closing down");
                    }
                }

                logger.Info("Displaying ViewModel {0} with View {1} as a Dialog", viewModel, window);
            }
            else
            {
                logger.Info("Displaying ViewModel {0} with View {1} as a Window", viewModel, window);
            }

            // If and only if they haven't tried to position the window themselves...
            // Has to be done after we're attempted to set the owner
            if (window.WindowStartupLocation == WindowStartupLocation.Manual && Double.IsNaN(window.Top) && Double.IsNaN(window.Left))
                window.WindowStartupLocation = window.Owner == null ? WindowStartupLocation.CenterScreen : WindowStartupLocation.CenterOwner;

            // This gets itself retained by the window, by registering events
            // ReSharper disable once ObjectCreationAsStatement
            new WindowConductor(window, viewModel);

            return window;
        }