| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739 | using System.Runtime.InteropServices;using System.Windows.Forms.VisualStyles;using System.Windows.Input;namespace Caliburn.Micro {    using System;    using System.Collections.Generic;    using System.ComponentModel;    using System.Windows;    using System.Windows.Controls;    using System.Windows.Controls.Primitives;    using System.Windows.Data;    using System.Linq;    using System.Windows.Navigation;    using Caliburn.Micro.Core;    using System.Windows.Media;    using OpenSEMI.Ctrlib.Window;    /// <summary>    /// A service that manages windows.    /// </summary>    public interface IWindowManager {        /// <summary>        /// Shows a modal dialog for the specified model.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The context.</param>        /// <param name="settings">The optional dialog settings.</param>        /// <returns>The dialog result.</returns>        bool? ShowDialog(object rootModel, object context = null, IDictionary<string, object> settings = null);        /// <summary>        /// Shows a non-modal window for the specified model.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The context.</param>        /// <param name="settings">The optional window settings.</param>        void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null);        /// <summary>        /// Shows a popup at the current mouse position.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The view context.</param>        /// <param name="settings">The optional popup settings.</param>        void ShowPopup(object rootModel, object context = null, IDictionary<string, object> settings = null);    }    /// <summary>    /// A service that manages windows.    /// </summary>    public class WindowManager : IWindowManager {        /// <summary>        /// Shows a modal dialog for the specified model.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The context.</param>        /// <param name="settings">The dialog popup settings.</param>        /// <returns>The dialog result.</returns>        public virtual bool? ShowDialog(object rootModel,  object context = null, IDictionary<string, object> settings = null){            Window window = CreateWindow(rootModel, true, context, settings);            window.ShowInTaskbar = false;            window.ResizeMode = ResizeMode.NoResize;            window.WindowStyle = WindowStyle.SingleBorderWindow;            return window.ShowDialog();        }        public virtual bool? ShowDialog(object rootModel, Point position, object context = null, IDictionary<string, object> settings = null)        {            Window window = CreateWindow(rootModel, true, context, settings);            window.ShowInTaskbar = false;            window.ResizeMode = ResizeMode.NoResize;            window.WindowStyle = WindowStyle.SingleBorderWindow;            window.WindowStartupLocation = WindowStartupLocation.Manual;            window.Owner = Application.Current.MainWindow;            window.Left = position.X;            window.Top = position.Y;            return window.ShowDialog();        }        public virtual bool? ShowDialog(object rootModel, Window owner, object context = null, IDictionary<string, object> settings = null)        {            Window window = CreateWindow(rootModel, true, context, settings);            window.ShowInTaskbar = false;            window.ResizeMode = ResizeMode.NoResize;            window.WindowStyle = WindowStyle.SingleBorderWindow;            window.Owner = owner;            return window.ShowDialog();        }        public virtual bool? ShowDialog(object rootModel, WindowState pWindowState , object context = null, IDictionary<string, object> settings = null)        {            Window window = CreateWindow(rootModel, true, context, settings);            window.ShowInTaskbar = false;            window.ResizeMode = ResizeMode.CanResize;            window.WindowStyle = WindowStyle.SingleBorderWindow;            window.WindowState = pWindowState;            return window.ShowDialog();        }        public virtual bool? ShowDialogWithNoWindow(object rootModel, object context = null, IDictionary<string, object> settings = null)        {            Window window = CreateWindow(rootModel, true, context, settings);            window.ShowInTaskbar = false;            window.ResizeMode = ResizeMode.NoResize;            window.WindowStyle = WindowStyle.None;            window.BorderThickness = new Thickness(1);            window.BorderBrush = new SolidColorBrush(Colors.Black);            return window.ShowDialog();        }        /// <summary>        /// Shows a special modal dialog for the specified model.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The context.</param>        /// <returns>The dialog result.</returns>        public virtual bool? ShowDialogWithNoStyle(object rootModel, object context = null)        {            Window window = CreateWindow(rootModel, true, context);            window.WindowStyle = WindowStyle.None;            window.AllowsTransparency = true;            window.ResizeMode = ResizeMode.NoResize;            window.Background = new SolidColorBrush(Colors.Transparent);            window.ShowInTaskbar = false;            window.WindowStartupLocation = WindowStartupLocation.CenterScreen;            window.Topmost = true;            return window.ShowDialog();        }        /// <summary>        /// Shows a special modal dialog for the specified model.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The context.</param>        /// <returns>The dialog result.</returns>        public virtual bool? ShowDialogWithTitle(object rootModel, object context = null, string title="")        {            Window window = CreateWindow(rootModel, true, context);            window.ShowInTaskbar = false;            window.ResizeMode = ResizeMode.NoResize;            window.WindowStyle = WindowStyle.SingleBorderWindow;            window.WindowStartupLocation = WindowStartupLocation.CenterScreen;            window.Title = title;            return window.ShowDialog();        }        /// <summary>        /// Shows a special modal dialog for the specified model.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The context.</param>        /// <returns>The dialog result.</returns>        public virtual bool? ShowCustomWndDialogWithTitle(object rootModel, object context = null, string title = "")        {            CustomWnd window = CreateCustomWnd(rootModel, true, context);            window.ShowInTaskbar = false;            window.ResizeMode = ResizeMode.NoResize;            window.WindowStyle = WindowStyle.SingleBorderWindow;            window.WindowStartupLocation = WindowStartupLocation.CenterScreen;            window.Title = title;            return window.ShowDialog();        }        /// <summary>        /// Creates a window.        /// </summary>        /// <param name="rootModel">The view model.</param>        /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>        /// <param name="context">The view context.</param>        /// <param name="createCompletedCallBack">Call back and return the new window when create window completed</param>        /// <returns>The window.</returns>        protected virtual Window CreateWindow(object rootModel, bool isDialog, object context, Action<Window> createCompletedCallBack = null)        {            var view = EnsureWindow(rootModel, ViewLocator.LocateForModel(rootModel, null, context), isDialog);            ViewModelBinder.Bind(rootModel, view, context);            var haveDisplayName = rootModel as IHaveDisplayName;            if (haveDisplayName != null && !ConventionManager.HasBinding(view, Window.TitleProperty))            {                var binding = new Binding("DisplayName") { Mode = BindingMode.OneWay };                view.SetBinding(Window.TitleProperty, binding);            }            if (createCompletedCallBack != null)            {                createCompletedCallBack(view);            }            new WindowConductor(rootModel, view);            return view;        }        /// <summary>        /// Creates a window.        /// </summary>        /// <param name="rootModel">The view model.</param>        /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>        /// <param name="context">The view context.</param>        /// <param name="createCompletedCallBack">Call back and return the new window when create window completed</param>        /// <returns>The window.</returns>        protected virtual CustomWnd CreateCustomWnd(object rootModel, bool isDialog, object context, Action<Window> createCompletedCallBack = null)        {            var view = EnsureCustomWnd(rootModel, ViewLocator.LocateForModel(rootModel, null, context), isDialog);            ViewModelBinder.Bind(rootModel, view, context);            var haveDisplayName = rootModel as IHaveDisplayName;            if (haveDisplayName != null && !ConventionManager.HasBinding(view, Window.TitleProperty))            {                var binding = new Binding("DisplayName") { Mode = BindingMode.OneWay };                view.SetBinding(CustomWnd.TitleProperty, binding);            }            if (createCompletedCallBack != null)            {                createCompletedCallBack(view);            }            new WindowConductor(rootModel, view);            return view;        }        /// <summary>        /// Makes sure the view is a window is is wrapped by one.        /// </summary>        /// <param name="model">The view model.</param>        /// <param name="view">The view.</param>        /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>        /// <returns>The window.</returns>        protected virtual CustomWnd EnsureCustomWnd(object model, object view, bool isDialog)        {            var window = view as CustomWnd;            if (window == null)            {                window = new CustomWnd                {                    Content = view,                    SizeToContent = SizeToContent.WidthAndHeight                };                window.SetValue(View.IsGeneratedProperty, true);                var owner = CustomWndInferOwnerOf(window);                if (owner != null)                {                    window.WindowStartupLocation = WindowStartupLocation.CenterOwner;                    window.Owner = owner;                }                else                {                    window.WindowStartupLocation = WindowStartupLocation.CenterScreen;                }            }            else            {                var owner = CustomWndInferOwnerOf(window);                if (owner != null && isDialog)                {                    window.Owner = owner;                }            }            return window;        }        /// <summary>        /// Infers the owner of the window.        /// </summary>        /// <param name="window">The window to whose owner needs to be determined.</param>        /// <returns>The owner.</returns>        protected virtual CustomWnd CustomWndInferOwnerOf(CustomWnd window)        {            var application = Application.Current;            if (application == null)            {                return null;            }            var active = application.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);            active = active ?? (PresentationSource.FromVisual(application.MainWindow) == null ? null : application.MainWindow);            return (CustomWnd)(active == window ? null : active);        }        /// <summary>        /// Shows a window for the specified model.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The context.</param>        /// <param name="settings">The optional window settings.</param>        public virtual void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null){            NavigationWindow navWindow = null;            var application = Application.Current;            if (application != null && application.MainWindow != null) {                navWindow = application.MainWindow as NavigationWindow;            }            if(navWindow != null) {                var window = CreatePage(rootModel, context, settings);                navWindow.Navigate(window);            }            else {                CreateWindow(rootModel, false, context, settings).Show();            }        }        /// <summary>        /// Shows a popup at the current mouse position.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The view context.</param>        /// <param name="settings">The optional popup settings.</param>        public virtual void ShowPopup(object rootModel, object context = null, IDictionary<string, object> settings = null) {            var popup = CreatePopup(rootModel, settings);            var view = ViewLocator.LocateForModel(rootModel, popup, context);            popup.Child = view;            popup.SetValue(View.IsGeneratedProperty, true);            ViewModelBinder.Bind(rootModel, popup, null);			Action.SetTargetWithoutContext(view, rootModel);            var activatable = rootModel as IActivate;            if (activatable != null) {                activatable.Activate();            }            var deactivator = rootModel as IDeactivate;            if (deactivator != null) {                popup.Closed += delegate { deactivator.Deactivate(true); };            }            popup.IsOpen = true;            popup.CaptureMouse();        }        /// <summary>        /// Creates a popup for hosting a popup window.        /// </summary>        /// <param name="rootModel">The model.</param>        /// <param name="settings">The optional popup settings.</param>        /// <returns>The popup.</returns>        protected virtual Popup CreatePopup(object rootModel, IDictionary<string, object> settings) {            var popup = new Popup();            if (ApplySettings(popup, settings)) {                if (!settings.ContainsKey("PlacementTarget") && !settings.ContainsKey("Placement"))                    popup.Placement = PlacementMode.MousePoint;                if (!settings.ContainsKey("AllowsTransparency"))                    popup.AllowsTransparency = true;            }else {                popup.AllowsTransparency = true;                popup.Placement = PlacementMode.MousePoint;            }            return popup;        }        /// <summary>        /// Creates a window.        /// </summary>        /// <param name="rootModel">The view model.</param>        /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>        /// <param name="context">The view context.</param>        /// <param name="settings">The optional popup settings.</param>        /// <returns>The window.</returns>        protected virtual Window CreateWindow(object rootModel, bool isDialog, object context, IDictionary<string, object> settings) {            var view = EnsureWindow(rootModel, ViewLocator.LocateForModel(rootModel, null, context), isDialog);            ViewModelBinder.Bind(rootModel, view, context);            var haveDisplayName = rootModel as IHaveDisplayName;            if (haveDisplayName != null && !ConventionManager.HasBinding(view, Window.TitleProperty)) {                var binding = new Binding("DisplayName") { Mode = BindingMode.TwoWay };                view.SetBinding(Window.TitleProperty, binding);            }            ApplySettings(view, settings);            new WindowConductor(rootModel, view);            return view;        }        /// <summary>        /// Makes sure the view is a window is is wrapped by one.        /// </summary>        /// <param name="model">The view model.</param>        /// <param name="view">The view.</param>        /// <param name="isDialog">Whethor or not the window is being shown as a dialog.</param>        /// <returns>The window.</returns>        protected virtual Window EnsureWindow(object model, object view, bool isDialog) {            var window = view as Window;            if (window == null) {                window = new Window {                    Content = view,                    SizeToContent = SizeToContent.WidthAndHeight                };                window.Width = ((UserControl)view).Width;                window.Height = ((UserControl)view).Height;                window.SetValue(View.IsGeneratedProperty, true);                var owner = InferOwnerOf(window);                if (owner != null) {                    window.WindowStartupLocation = WindowStartupLocation.CenterOwner;                    window.Owner = owner;                }                else {                    window.WindowStartupLocation = WindowStartupLocation.CenterScreen;                }            }            else {                var owner = InferOwnerOf(window);                if (owner != null && isDialog) {                    window.Owner = owner;                }            }            return window;        }        /// <summary>        /// Infers the owner of the window.        /// </summary>        /// <param name="window">The window to whose owner needs to be determined.</param>        /// <returns>The owner.</returns>        protected virtual Window InferOwnerOf(Window window) {            var application = Application.Current;            if (application == null) {                return null;            }            var active = application.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);            active = active ?? (PresentationSource.FromVisual(application.MainWindow) == null ? null : application.MainWindow);            return active == window ? null : active;        }        /// <summary>        /// Creates the page.        /// </summary>        /// <param name="rootModel">The root model.</param>        /// <param name="context">The context.</param>        /// <param name="settings">The optional popup settings.</param>        /// <returns>The page.</returns>        public virtual Page CreatePage(object rootModel, object context, IDictionary<string, object> settings) {            var view = EnsurePage(rootModel, ViewLocator.LocateForModel(rootModel, null, context));            ViewModelBinder.Bind(rootModel, view, context);            var haveDisplayName = rootModel as IHaveDisplayName;            if (haveDisplayName != null && !ConventionManager.HasBinding(view, Page.TitleProperty)) {                var binding = new Binding("DisplayName") { Mode = BindingMode.TwoWay };                view.SetBinding(Page.TitleProperty, binding);            }            ApplySettings(view, settings);            var activatable = rootModel as IActivate;            if (activatable != null) {                activatable.Activate();            }            var deactivatable = rootModel as IDeactivate;            if (deactivatable != null) {                view.Unloaded += (s, e) => deactivatable.Deactivate(true);            }            return view;        }        /// <summary>        /// Ensures the view is a page or provides one.        /// </summary>        /// <param name="model">The model.</param>        /// <param name="view">The view.</param>        /// <returns>The page.</returns>        protected virtual Page EnsurePage(object model, object view) {            var page = view as Page;            if(page == null) {                page = new Page { Content = view };                page.SetValue(View.IsGeneratedProperty, true);            }            return page;        }        bool ApplySettings(object target, IEnumerable<KeyValuePair<string, object>> settings) {            if (settings != null) {                var type = target.GetType();                foreach (var pair in settings) {                    var propertyInfo = type.GetProperty(pair.Key);                    if (propertyInfo != null) {                        propertyInfo.SetValue(target, pair.Value, null);                    }                }                return true;            }            return false;        }        class WindowConductor {            bool deactivatingFromView;            bool deactivateFromViewModel;            bool actuallyClosing;            readonly Window view;            readonly object model;            public WindowConductor(object model, Window view) {                this.model = model;                this.view = view;                var activatable = model as IActivate;                if (activatable != null) {                    activatable.Activate();                }                var deactivatable = model as IDeactivate;                if (deactivatable != null) {                    view.Closed += Closed;                    deactivatable.Deactivated += Deactivated;                }                var guard = model as IGuardClose;                if (guard != null) {                    view.Closing += Closing;                }            }            void Closed(object sender, EventArgs e) {                view.Closed -= Closed;                view.Closing -= Closing;                if (deactivateFromViewModel) {                    return;                }                var deactivatable = (IDeactivate)model;                deactivatingFromView = true;                deactivatable.Deactivate(true);                deactivatingFromView = false;            }            void Deactivated(object sender, DeactivationEventArgs e) {                if (!e.WasClosed) {                    return;                }                ((IDeactivate)model).Deactivated -= Deactivated;                if (deactivatingFromView) {                    return;                }                deactivateFromViewModel = true;                actuallyClosing = true;                view.Close();                actuallyClosing = false;                deactivateFromViewModel = false;            }            void Closing(object sender, CancelEventArgs e) {                if (e.Cancel) {                    return;                }                var guard = (IGuardClose)model;                if (actuallyClosing) {                    actuallyClosing = false;                    return;                }                bool runningAsync = false, shouldEnd = false;                guard.CanClose(canClose => {                    Execute.OnUIThread(() => {                        if(runningAsync && canClose) {                            actuallyClosing = true;                            view.Close();                        }                        else {                            e.Cancel = !canClose;                        }                        shouldEnd = true;                    });                });                if (shouldEnd) {                    return;                }                runningAsync = e.Cancel = true;            }        }    }     public static class WindowExtensions    {        #region Public Methods        public static bool ActivateCenteredToMouse(this Window window)        {            ComputeTopLeft(ref window);            return window.Activate();        }        public static void ShowCenteredToMouse(this Window window)        {            // in case the default start-up location isn't set to Manual            WindowStartupLocation oldLocation = window.WindowStartupLocation;            // set location to manual -> window will be placed by Top and Left property            window.WindowStartupLocation = WindowStartupLocation.Manual;            ComputeTopLeft(ref window);            window.ShowDialog();            window.WindowStartupLocation = oldLocation;        }        #endregion        #region Methods        private static void ComputeTopLeft(ref Window window)        {            W32Point pt = new W32Point();            if (!GetCursorPos(ref pt))            {                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());            }            // 0x00000002: return nearest monitor if pt is not contained in any monitor.            IntPtr monHandle = MonitorFromPoint(pt, 0x00000002);            W32MonitorInfo monInfo = new W32MonitorInfo();            monInfo.Size = Marshal.SizeOf(typeof(W32MonitorInfo));            if (!GetMonitorInfo(monHandle, ref monInfo))            {                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());            }            // use WorkArea struct to include the taskbar position.            W32Rect monitor = monInfo.WorkArea;            double offsetX = Math.Round(window.Width / 2);            double offsetY = Math.Round(window.Height / 2);            double top = pt.Y - offsetY;            double left = pt.X - offsetX;            Rect screen = new Rect(                new Point(monitor.Left, monitor.Top),                new Point(monitor.Right, monitor.Bottom));            Rect wnd = new Rect(                new Point(left, top),                new Point(left + window.Width, top + window.Height));            window.Top = wnd.Top;            window.Left = wnd.Left;            if (!screen.Contains(wnd))            {                if (wnd.Top < screen.Top)                {                    double diff = Math.Abs(screen.Top - wnd.Top);                    window.Top = wnd.Top + diff;                }                if (wnd.Bottom > screen.Bottom)                {                    double diff = wnd.Bottom - screen.Bottom;                    window.Top = wnd.Top - diff;                }                if (wnd.Left < screen.Left)                {                    double diff = Math.Abs(screen.Left - wnd.Left);                    window.Left = wnd.Left + diff;                }                if (wnd.Right > screen.Right)                {                    double diff = wnd.Right - screen.Right;                    window.Left = wnd.Left - diff;                }            }        }        #endregion        #region W32 API        [DllImport("user32.dll", SetLastError = true)]        [return: MarshalAs(UnmanagedType.Bool)]        private static extern bool GetCursorPos(ref W32Point pt);        [DllImport("user32.dll", SetLastError = true)]        [return: MarshalAs(UnmanagedType.Bool)]        private static extern bool GetMonitorInfo(IntPtr hMonitor, ref W32MonitorInfo lpmi);        [DllImport("user32.dll")]        private static extern IntPtr MonitorFromPoint(W32Point pt, uint dwFlags);        [StructLayout(LayoutKind.Sequential)]        public struct W32Point        {            public int X;            public int Y;        }        [StructLayout(LayoutKind.Sequential)]        internal struct W32MonitorInfo        {            public int Size;            public W32Rect Monitor;            public W32Rect WorkArea;            public uint Flags;        }        [StructLayout(LayoutKind.Sequential)]        internal struct W32Rect        {            public int Left;            public int Top;            public int Right;            public int Bottom;        }        #endregion    }}
 |