WPF C# 将 Window 发送到屏幕并对齐

WPF C# Send Window to Screen and align

我正在尝试将 window 发送到屏幕,并将 window 放在屏幕中央。单击按钮时,它会发送/关闭 window 并更改按钮内容。

我的第一个问题是我可以打开和关闭 Window,但只有 1 次。我第二次收到: System.InvalidOperationException: 'Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.'

另外,手动关闭按钮,不会改变按钮内容。

最后,它没有将 window 放在屏幕中央。我尝试使用以下方法将 window 放置在屏幕中央:

window.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
window.VerticalAlignment = VerticalAlignment.Center;

但这不起作用,它放置在window左上角。

有人可以指导我如何处理这个问题吗?

Window1 w1 = new Window1();

private void ShowByCoordinates(Window window, string screenName, int LeftTransform, int TopTransform)
    {

        if (button4.Content.ToString() == "Send")
        {
            Screen s0 = Screen.AllScreens.FirstOrDefault(s => s.DeviceName == screenName) ?? Screen.PrimaryScreen;
            Rectangle bounds = s0.WorkingArea;
            window.Left = bounds.X + LeftTransform;
            window.Top = bounds.Y + TopTransform;
            window.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            window.VerticalAlignment = VerticalAlignment.Center;
            window.Show();
            button4.Content = "Stop";
        }
        else
        {
            window.Close();
            button4.Content = "Send";
        }
    }

private void Button4_Click(object sender, RoutedEventArgs e)
    {
        ShowByCoordinates(w1, "DISPLAY2", 1920, 0);
    }

首先,如果你 Close window,你不能像已经提到的那样再次 Show 它。您需要使用 Hide 而不是 Close

要使屏幕居中,只需使用以下行:

this.WindowStartupLocation = WindowStartupLocation.CenterScreen;

首先,一旦您关闭 window,它就会被处理掉,您将无法再次显示它。请改用 Show()Hide()

当您将 WindowStartupLocation 设置为 CenterScreen 时,会出现一个问题:显示 window 后,对其位置的任何编程更改都将被忽略。所以这种方式只能做一次。

要手动执行此操作,您需要将 WindowStartupLocation 设置为 Manual,然后设置您的 window 的 TopLeft 属性。

您必须考虑的下一个问题是可能有多个显示器。如果您只需要将 window 集中在系统中设置为主要的监视器上,则:

w.Left = (SystemParameters.WorkArea.Width - w.ActualWidth) / 2 + SystemParameters.WorkArea.Left;
w.Top = (SystemParameters.WorkArea.Height - w.ActualHeight) / 2 + SystemParameters.WorkArea.Top

够了。如果你想让 window 在当前显示器上居中,那么你需要做这样的事情:

(来自 here 的方法):

public static void PostitionWindowOnScreen(Window window, double horizontalShift = 0, double verticalShift = 0)
{
    Screen screen = Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(window).Handle);
    window.Left = screen.Bounds.X + ((screen.Bounds.Width - window.ActualWidth) / 2) + horizontalShift;
    window.Top = screen.Bounds.Y + ((screen.Bounds.Height - window.ActualHeight) / 2) + verticalShift;
}

调用它:

TestWindow w;

//....

w = new TestWindow();
w.WindowStartupLocation = WindowStartupLocation.Manual;
w.Closed += w_Closed;

//....

private void w_Closed(object sender, EventArgs e)
{
    // to make sure there is no disposed window to access when user closes it manually
    w = null;
    // or:
    // w = new TestWindow();
}

private void Button_ShowWindow_Click(object sender, RoutedEventArgs e)
{
      if (w == null) return;
      PostitionWindowOnScreen(w, 0, 0);
      w.Show();
}

private void Button_HideWindow_Click(object sender, RoutedEventArgs e)
{
    if (w == null) return;
    w.Hide();
}