C# 恢复辅助监视器上的最大化状态

C# 恢复辅助监视器上的最大化状态,c#,wpf,C#,Wpf,当我在辅助监视器上最大化窗口时,我有一个关于恢复窗口状态的问题。 我将非主屏幕上的窗口最大化,然后关闭。 当重新打开窗口时,它也会最大化,但在主屏幕上会最大化。 我希望在非主屏幕(关闭时的屏幕显示窗口)上最大化 如果你知道,请帮助我 注意:若窗口状态正常,窗口将恢复到正确的屏幕 我的代码如下: if (ShellState == WindowState.Maximized) { ShellState = WindowState.Normal;

当我在辅助监视器上最大化窗口时,我有一个关于恢复窗口状态的问题。 我将非主屏幕上的窗口最大化,然后关闭。 当重新打开窗口时,它也会最大化,但在主屏幕上会最大化。 我希望在非主屏幕(关闭时的屏幕显示窗口)上最大化

如果你知道,请帮助我

注意:若窗口状态正常,窗口将恢复到正确的屏幕

我的代码如下:

 if (ShellState == WindowState.Maximized)
        {
            ShellState = WindowState.Normal;
            LeftPosition = Screen.AllScreens[selectedScreen].WorkingArea.Left;
            TopPosition = Screen.AllScreens[selectedScreen].WorkingArea.Top;
            ShellHeight = Screen.AllScreens[selectedScreen].WorkingArea.Height;
            ShellWidth = Screen.AllScreens[selectedScreen].WorkingArea.Width;
            ShellState = WindowState.Maximized;
        }

在使用标准WPF工具存储和恢复窗口状态和大小的多屏幕系统上,我们遇到了许多问题,只要屏幕分配不变

我们开始创建使用本机WinAPI函数的自定义行为。 以下是我们行为的(简化)源代码。您可以在应用程序中使用它,而不是WPF工具

您必须更改窗口位置的存储方式。这可以是提供容器的依赖属性、静态
属性、设置
引用或其他内容。在下面的代码中,使用静态
ApplicationSettings
参考作为示例

class WindowPlacementPersistenceBehavior : Behavior<Window>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.SourceInitialized += this.AssociatedObject_SourceInitialized;
        this.AssociatedObject.Closing += this.AssociatedObject_Closing;
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.SourceInitialized -= this.AssociatedObject_SourceInitialized;
        this.AssociatedObject.Closing -= this.AssociatedObject_Closing;
        base.OnDetaching();
    }

    private void AssociatedObject_Closing(object sender, CancelEventArgs e)
    {
        WINDOWPLACEMENT wp;
        NativeMethods.GetWindowPlacement(new WindowInteropHelper(this.AssociatedObject).Handle, out wp);

        // Here you can store the window placement
        ApplicationSettings.WindowPlacement = wp.ToString();
    }

    private void AssociatedObject_SourceInitialized(object sender, EventArgs e)
    {
        // Here you can load the window placement
        WINDOWPLACEMENT wp = WINDOWPLACEMENT.Parse(ApplicationSettings.WindowPlacement);
        if (wp.ShowCmd == NativeMethods.SW_SHOWMINIMIZED)
        {
            // Don't start in the minimized state
            wp.ShowCmd = NativeMethods.SW_SHOWNORMAL;
        }

        try
        {
            NativeMethods.SetWindowPlacement(new WindowInteropHelper(this.AssociatedObject).Handle, ref wp);
        }
        catch
        {
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;

        public static RECT Parse(string input)
        {
            RECT result;
            string[] items = input.Split(';');
            result.Left = int.Parse(items[0]);
            result.Top = int.Parse(items[1]);
            result.Right = int.Parse(items[2]);
            result.Bottom = int.Parse(items[3]);
            return result;
        }

        public override string ToString()
        {
            return this.Left + ";" + this.Top + ";" + this.Right + ";" + this.Bottom;
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    private struct POINT
    {
        public int X;
        public int Y;

        public static POINT Parse(string input)
        {
            POINT result;
            string[] items = input.Split(';');
            result.X = int.Parse(items[0]);
            result.Y = int.Parse(items[1]);
            return result;
        }

        public override string ToString()
        {
            return this.X + ";" + this.Y;
        }
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    private struct WINDOWPLACEMENT
    {
        public int Length;
        public int Flags;
        public int ShowCmd;
        public POINT MinPosition;
        public POINT MaxPosition;
        public RECT NormalPosition;

        public static WINDOWPLACEMENT Parse(string input)
        {
            WINDOWPLACEMENT result = default(WINDOWPLACEMENT);
            result.Length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
            try
            {
                string[] items = input.Split('/');
                result.Flags = int.Parse(items[0]);
                result.ShowCmd = int.Parse(items[1]);
                result.MinPosition = POINT.Parse(items[2]);
                result.MaxPosition = POINT.Parse(items[3]);
                result.NormalPosition = RECT.Parse(items[4]);
            }
            catch
            {
            }

            return result;
        }

        public override string ToString()
        {
            return this.Flags + "/" + this.ShowCmd + "/" + this.MinPosition.ToString() + "/" + this.MaxPosition.ToString() + "/" + this.NormalPosition.ToString();
        }
    }

    private static class NativeMethods
    {
        public const int SW_SHOWNORMAL = 1;
        public const int SW_SHOWMINIMIZED = 2;

        [DllImport("user32.dll")]
        public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);

        [DllImport("user32.dll")]
        public static extern bool GetWindowPlacement(IntPtr hWnd, [Out] out WINDOWPLACEMENT lpwndpl);
    }
}
class WindowPlacementPersistenceBehavior:Behavior
{
受保护的覆盖无效附加()
{
base.onatached();
this.AssociatedObject.SourceInitialized+=this.AssociatedObject\u SourceInitialized;
this.AssociatedObject.Closing+=this.AssociatedObject\u Closing;
}
附加时受保护的覆盖无效()
{
this.AssociatedObject.SourceInitialized-=this.AssociatedObject\u SourceInitialized;
this.AssociatedObject.Closing-=this.AssociatedObject\u Closing;
base.OnDetaching();
}
私有无效关联对象\u关闭(对象发送方,取消事件参数e)
{
窗口放置可湿性粉剂;
NativeMethods.GetWindowPlacement(新的WindowInteropHelper(this.AssociatedObject).Handle,out wp);
//您可以在此处存储窗口位置
ApplicationSettings.WindowPlacement=wp.ToString();
}
private void AssociatedObject\u SourceInitialized(对象发送方,事件参数e)
{
//您可以在此处加载窗口放置
WINDOWPLACEMENT wp=WINDOWPLACEMENT.Parse(ApplicationSettings.WINDOWPLACEMENT);
如果(wp.ShowCmd==NativeMethods.SW_)
{
//不要在最小化状态下启动
wp.ShowCmd=NativeMethods.SW_SHOWNORMAL;
}
尝试
{
NativeMethods.SetWindowPlacement(新的WindowInteropHelper(this.AssociatedObject).Handle,ref-wp);
}
抓住
{
}
}
[可序列化]
[StructLayout(LayoutKind.Sequential)]
私有结构矩形
{
公共int左;
公共int Top;
公共权利;
公共int底部;
公共静态RECT解析(字符串输入)
{
直接结果;
string[]items=input.Split(“;”);
result.Left=int.Parse(项[0]);
result.Top=int.Parse(项[1]);
result.Right=int.Parse(项目[2]);
result.Bottom=int.Parse(项目[3]);
返回结果;
}
公共重写字符串ToString()
{
返回this.Left+“;”+this.Top+“;”+this.Right+“;”+this.Bottom;
}
}
[可序列化]
[StructLayout(LayoutKind.Sequential)]
私有结构点
{
公共int X;
公共智力;
公共静态点解析(字符串输入)
{
积分结果;
string[]items=input.Split(“;”);
result.X=int.Parse(项[0]);
result.Y=int.Parse(项[1]);
返回结果;
}
公共重写字符串ToString()
{
返回这个.X+“;”+这个.Y;
}
}
[可序列化]
[StructLayout(LayoutKind.Sequential)]
私有结构窗口放置
{
公共整数长度;
公共国旗;
公共int ShowCmd;
公共点位置;
公共点位置;
公众的正常立场;
公共静态WINDOWPLACEMENT解析(字符串输入)
{
WINDOWPLACEMENT结果=默认值(WINDOWPLACEMENT);
result.Length=Marshal.SizeOf(typeof(WINDOWPLACEMENT));
尝试
{
string[]items=input.Split('/');
result.Flags=int.Parse(项[0]);
result.ShowCmd=int.Parse(项目[1]);
result.MinPosition=POINT.Parse(项目[2]);
result.MaxPosition=POINT.Parse(项目[3]);
result.NormalPosition=RECT.Parse(项目[4]);
}
抓住
{
}
返回结果;
}
公共重写字符串ToString()
{
返回this.Flags+“/”+this.ShowCmd+“/”+this.MinPosition.ToString()+“/”+this.MaxPosition.ToString()+“/”+this.NormalPosition.ToString();
}
}
私有静态类NativeMethods
{
公共const int SW_SHOWNORMAL=1;
公共常数int SW_=2;
[DllImport(“user32.dll”)]
公共静态外部bool SetWindowPlacement(IntPtr hWnd,[In]ref WINDOWPLACEMENT lpwndpl);
[DllImport(“user32.dll”)]
公共静态外部bool GetWindowPlacement(IntPtr hWnd,[Out]Out WINDOWPLACEMENT lpwndpl);
}
}
要使用此行为,只需将其添加到XAML中的窗口:

<Window
    xmlns:v="clr-namespace:YourNameSpace"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Behaviors>
    <v:WindowPlacementPersistenceBehavior />
</i:Interaction.Behaviors>
</Window>