Exemplo n.º 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 = 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);
            }
        }
Exemplo n.º 2
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 = 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 = 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;
		}