微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 记住窗口位置,大小和状态[在Win箭头对齐](带多个监视器)

在我们的项目中,我们保存了窗口大小,位置和最小化/最大化设置,因此我们可以在重新打开窗口时以完全相同的点和大小打开窗口.所有这一切都运行得很好,使用了本文底部的Window-Behavior-class.

但问题是,当我们使用Win-button箭头时;这会将屏幕与屏幕一侧对齐,但这并未正确保存在行为中.相反,它在我使用Win箭头对齐它之前保存了屏幕的位置和大小,这就是它再次打开的位置.

我试图在SaveWindowState方法中使用Window的Left,Top,ActualWidth和ActualHeight(注意:此方法中的Associatedobject是Window.)但是Left和Top似乎关闭了大约20-40像素,并且使用ActualWidth,ActualHeight和当前屏幕宽度/高度(使用多个显示器时)保存Right和Left也有点痛苦.

那么,当用户使用Win箭头对齐Window然后关闭它时,有没有办法在窗口设置中保存正确的位置和大小?

WindowSettingsBehavior:

using System;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Interop;

namespace NatWa.MidOffice.Behaviors
{
    /// <summary>
    /// Persists a Window's Size,Location and WindowState to UserScopeSettings 
    /// </summary>
    public class WindowSettingsBehavior : Behavior<Window>
    {
        [DllImport("user32.dll")]
        static extern bool SetwindowPlacement(IntPtr hWnd,[In] ref Windowplacement lpwndpl);

        [DllImport("user32.dll")]
        static extern bool GetwindowPlacement(IntPtr hWnd,out Windowplacement lpwndpl);

        // ReSharper disable InconsistentNaming
        const int SW_SHOWnorMAL = 1;
        const int SW_SHOWMINIMIZED = 2;
        // ReSharper restore InconsistentNaming

        internal class WindowApplicationSettings : ApplicationSettingsBase
        {
            public WindowApplicationSettings(WindowSettingsBehavior windowSettingsBehavior)
                : base(windowSettingsBehavior.Associatedobject.GetType().FullName)
            {
            }

            [UserScopedSetting]
            public Windowplacement? Placement
            {
                get
                {
                    if (this["Placement"] != null)
                    {
                        return ((Windowplacement)this["Placement"]);
                    }
                    return null;
                }
                set
                {
                    this["Placement"] = value;
                }
            }
        }

        /// <summary>
        /// Load the Window Size Location and State from the settings object
        /// </summary>
        private void LoadWindowState()
        {
            Settings.Reload();

            if (Settings.Placement == null) return;
            try
            {
                // Load window placement details for prevIoUs application session from application settings.
                // If window was closed on a monitor that is Now disconnected from the computer,// SetwindowPlacement will place the window onto a visible monitor.
                var wp = Settings.Placement.Value;

                wp.length = Marshal.SizeOf(typeof(Windowplacement));
                wp.flags = 0;
                wp.showCmd = (wp.showCmd == SW_SHOWMINIMIZED ? SW_SHOWnorMAL : wp.showCmd);
                var hwnd = new WindowInteropHelper(Associatedobject).Handle;
                SetwindowPlacement(hwnd,ref wp);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Failed to load window state:\r\n{0}",ex);
            }
        }

        /// <summary>
        /// Save the Window Size,Location and State to the settings object
        /// </summary>
        private void SaveWindowState()
        {
            Windowplacement wp;
            var hwnd = new WindowInteropHelper(Associatedobject).Handle;

            GetwindowPlacement(hwnd,out wp);
            Settings.Placement = wp;
            Settings.Save();
        }

        protected override void OnAttached()
        {
            base.OnAttached();
            Associatedobject.Closing += WindowClosing;
            Associatedobject.sourceInitialized += WindowSourceInitialized;
        }

        private void WindowSourceInitialized(object sender,EventArgs e)
        {
            LoadWindowState();
        }

        private void WindowClosing(object sender,CancelEventArgs e)
        {
            SaveWindowState();
            Associatedobject.Closing -= WindowClosing;
            Associatedobject.sourceInitialized -= WindowSourceInitialized;
        }

        private WindowApplicationSettings _windowApplicationSettings;

        internal virtual WindowApplicationSettings CreateWindowApplicationSettingsInstance()
        {
            return new WindowApplicationSettings(this);
        }

        [browsable(false)]
        internal WindowApplicationSettings Settings
        {
            get { return _windowApplicationSettings
                ?? (_windowApplicationSettings = CreateWindowApplicationSettingsInstance()); }
        }
    }

    #region Save position classes

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct Rect
    {
        private int _left;
        private int _top;
        private int _right;
        private int _bottom;

        public Rect(int left,int top,int right,int bottom)
        {
            _left = left;
            _top = top;
            _right = right;
            _bottom = bottom;
        }

        public override bool Equals(object obj)
        {
            if (!(obj is Rect)) return base.Equals(obj);

            var rect = (Rect)obj;
            return rect._bottom == _bottom &&
                   rect._left == _left &&
                   rect._right == _right &&
                   rect._top == _top;
        }

        public override int GetHashCode()
        {
            return _bottom.GetHashCode() ^
                   _left.GetHashCode() ^
                   _right.GetHashCode() ^
                   _top.GetHashCode();
        }

        public static bool operator ==(Rect a,Rect b)
        {
            return a._bottom == b._bottom &&
                   a._left == b._left &&
                   a._right == b._right &&
                   a._top == b._top;
        }

        public static bool operator !=(Rect a,Rect b)
        {
            return !(a == b);
        }

        public int Left
        {
            get { return _left; }
            set { _left = value; }
        }

        public int Top
        {
            get { return _top; }
            set { _top = value; }
        }

        public int Right
        {
            get { return _right; }
            set { _right = value; }
        }

        public int Bottom
        {
            get { return _bottom; }
            set { _bottom = value; }
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct Point
    {
        private int _x;
        private int _y;

        public Point(int x,int y)
        {
            _x = x;
            _y = y;
        }

        public int X
        {
            get { return _x; }
            set { _x = value; }
        }

        public int Y
        {
            get { return _y; }
            set { _y = value; }
        }

        public override bool Equals(object obj)
        {
            if (!(obj is Point)) return base.Equals(obj);
            var point = (Point)obj;

            return point._x == _x && point._y == _y;
        }

        public override int GetHashCode()
        {
            return _x.GetHashCode() ^ _y.GetHashCode();
        }

        public static bool operator ==(Point a,Point b)
        {
            return a._x == b._x && a._y == b._y;
        }

        public static bool operator !=(Point a,Point b)
        {
            return !(a == b);
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct Windowplacement
    {
        public int length;
        public int flags;
        public int showCmd;
        public Point minPosition;
        public Point maxPosition;
        public Rect normalPosition;
    }

    #endregion
}

解决方法

您是否尝试过System.Windows.Window实例而不是p / invoke?
我使用两个简单的方法来保存和设置窗口位置使用这个类,它可以在不同的应用程序,架构,客户端,Windows操作系统,有或没有Aero的情况下完美地工作…
void SetwindowPosition()
{
    this.Left = Settings.Default.WindowPositionLeft;
    this.Top = Settings.Default.WindowPositionTop;
}
void SaveWindowPosition()
{
    Settings.Default.WindowPositionTop = this.Top;
    Settings.Default.WindowPositionLeft = this.Left;
    Settings.Default.Save();
}

或者我错过了什么?

原文地址:https://www.jb51.cc/csharp/99758.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐