如何将主窗口置于WPF中心?

时间:2010-10-26 00:20:58

标签: c# wpf window center

我有一个WPF应用程序,我需要知道如何以编程方式(而不是XAML)将wain窗口居中。

我需要能够在启动时和响应某些用户事件时执行此操作。它必须动态计算,因为窗口大小本身是动态的。

最简单的方法是什么?在旧的Win32代码下,我会调用系统指标函数并完成所有工作。这仍然是它的完成方式,还是我现在可以调用的简单CenterWindowOnScreen()函数。

14 个答案:

答案 0 :(得分:92)

嗯,对于启动时间,您可以设置startup location

window.WindowStartupLocation = WindowStartupLocation.CenterScreen;

稍后,您需要查询它。信息(至少主屏幕)可通过SystemParameters.PrimaryScreenWidth / Height。

获取

答案 1 :(得分:72)

private void CenterWindowOnScreen()
{
    double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
    double screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
    double windowWidth = this.Width;
    double windowHeight = this.Height;
    this.Left = (screenWidth / 2) - (windowWidth / 2);
    this.Top = (screenHeight / 2) - (windowHeight / 2);
}

您可以使用此方法将窗口位置设置为屏幕中心。

答案 2 :(得分:65)

设置

不是那么简单
WindowStartupLocation="CenterScreen"

在窗口的XAML定义中。

答案 3 :(得分:22)

Rect workArea = System.Windows.SystemParameters.WorkArea;
this.Left = (workArea.Width - this.Width) / 2 + workArea.Left;
this.Top = (workArea.Height - this.Height) / 2 + workArea.Top;

这会考虑任务栏的大小(使用System.Windows.SystemParameters.WorkArea)和位置(通过添加workArea.LeftworkArea.Top

答案 4 :(得分:13)

我必须结合其中一些答案来涵盖我案例中的所有基础:

  • Peter's method找到当前的监视器 - 而不仅仅是主监视器(严重的是谁只有1个监视器在工作了?)
  • @ Wild_A's method使用workarea而不是screen bounds来考虑任务栏的空间。
  • 我不得不添加DPI缩放,专门用于将1280x800显示为1024x640的平板电脑,但这对覆盖边缘情况非常有用,为此我找到了here的答案。请注意,如果在显示UI之前首次加载时调用dpiScaling变量为空(explained here
//get the current monitor
Screen currentMonitor = Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(Application.Current.MainWindow).Handle);

//find out if our app is being scaled by the monitor
PresentationSource source = PresentationSource.FromVisual(Application.Current.MainWindow);
double dpiScaling = (source != null && source.CompositionTarget != null ? source.CompositionTarget.TransformFromDevice.M11 : 1);

//get the available area of the monitor
Rectangle workArea = currentMonitor.WorkingArea;
var workAreaWidth = (int)Math.Floor(workArea.Width*dpiScaling);
var workAreaHeight = (int)Math.Floor(workArea.Height*dpiScaling);

//move to the centre
Application.Current.MainWindow.Left = (((workAreaWidth - (myWindowWidth * dpiScaling)) / 2) + (workArea.Left * dpiScaling));
Application.Current.MainWindow.Top = (((workAreaHeight - (myWindowHeight * dpiScaling)) / 2) + (workArea.Top * dpiScaling));

其中myWindowWidthmyWindowHeight是我之前手动设置窗口大小的变量。

答案 5 :(得分:5)

在window元素中添加此属性值对: 的 WindowStartupLocation ="中心屏幕"

答案 6 :(得分:5)

如果您需要在多屏幕环境中绘制窗口。 我已经创建了一个静态类,可以重用以下方法:

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;        
}

在Window的构造函数中,现在只需调用方法:

this.Loaded += (s, a) => Globals.PostitionWindowOnScreen(this, 0, 0)

答案 7 :(得分:4)

作为基本解决方案,您可以使用窗口的StartupLocation属性,将其设置为System.Windows.WindowStartupLocation枚举中定义的枚举值之一,有一个用于屏幕中心:

_wpfWindow.StartupLocation = System.Windows.WindowStartupLocation.CenterScreen;

不幸的是,它并不总是那么简单;您需要考虑多个监视器,任务栏等。“CenterScreen”选项打开屏幕中央有鼠标光标的窗口。有关大量信息,请参阅this SO question,或参考api

答案 8 :(得分:1)

我在我的应用程序中使用的是什么,它适用于多种显示和不同的DPI设置

    //center a window on chosen screen
    public static void CenterWindow(Window w, System.Windows.Forms.Screen screen = null)
    {
        if(screen == null)
            screen = System.Windows.Forms.Screen.PrimaryScreen;

        int screenW = screen.Bounds.Width;
        int screenH = screen.Bounds.Height;
        int screenTop = screen.Bounds.Top;
        int screenLeft = screen.Bounds.Left;

        w.Left = PixelsToPoints((int)(screenLeft + (screenW - PointsToPixels(w.Width, "X")) / 2), "X");
        w.Top = PixelsToPoints((int)(screenTop + (screenH - PointsToPixels(w.Height, "Y")) / 2), "Y");
    }

    public static double PixelsToPoints(int pixels, string direction)
    {
        if (direction == "X")
        {
            return pixels * SystemParameters.WorkArea.Width / System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
        }
        else
        {
            return pixels * SystemParameters.WorkArea.Height / System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
        }
    }

    public static double PointsToPixels(double wpfPoints, string direction)
    {
        if (direction == "X")
        {
            return wpfPoints * System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width / SystemParameters.WorkArea.Width;
        }
        else
        {
            return wpfPoints * System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height / SystemParameters.WorkArea.Height;
        }
    }

答案 9 :(得分:0)

如果你立刻最大化了     this.WindowState = System.Windows.WindowState.Maximized;

答案 10 :(得分:0)

根据@Wild_A回答,我刚刚订阅了SizeChanged事件,并添加了此事件处理程序:

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
    try
    {
        Rect workArea = SystemParameters.WorkArea;
        this.Left = (workArea.Width - e.NewSize.Width) / 2 + workArea.Left;
        this.Top = (workArea.Height - e.NewSize.Height) / 2 + workArea.Top;
    }
    catch (Exception ex) { ... Handel exception; }
}

答案 11 :(得分:0)

转到MainWindow.xaml的属性窗口

    从“常见”类别中
  • 找到 WindowStartupLocation 属性
  • 从下拉菜单中选择 CenterScreen 选项
  • 运行应用程序

对于全屏

转到MainWindow.xaml的属性窗口

    从“常见”类别中
  • 找到 WindowState 属性
  • 从下拉菜单中选择最大化选项
  • 运行应用程序

答案 12 :(得分:0)

复制粘贴高质量的扩展代码。

运行时:

using System;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;

namespace Extensions
{
    /// <summary>
    /// <see cref="Window"/> extensions.
    /// </summary>
    public static class WindowExtensions
    {
        /// <summary>
        /// Moves the window to the center of the current screen, also considering dpi.
        /// </summary>
        /// <param name="window"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public static void MoveToCenter(this Window window)
        {
            window = window ?? throw new ArgumentNullException(nameof(window));

            var helper = new WindowInteropHelper(window);
            var screen = Screen.FromHandle(helper.Handle);
            var area = screen.WorkingArea;

            var source = PresentationSource.FromVisual(window);
            var dpi = source?.CompositionTarget?.TransformFromDevice.M11 ?? 1.0;

            window.Left = dpi * area.Left + (dpi * area.Width - window.Width) / 2;
            window.Top = dpi * area.Top + (dpi * area.Height - window.Height) / 2;
        }
    }
}

初始位置:

<Window WindowStartupLocation="CenterScreen">
</Window>

答案 13 :(得分:-1)

您将必须找到此行: Title =“ MainWindow” Height =“ 450” Width =“ 800”

添加此行: WindowStartupLocation =“ CenterScreen”

要成为这个: Title =“ MainWindow” Height =“ 450” Width =“ 800” WindowStartupLocation =“ CenterScreen”>

稍后感谢我♥