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

pax*_*blo 52 c# wpf window center

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

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

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

Ree*_*sey 97

那么,对于启动时间,您可以设置启动位置:

window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
Run Code Online (Sandbox Code Playgroud)

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


Nop*_*det 74

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);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 仅当您有1台显示器或所有显示器的大小相同时,此功能才有效 (8认同)

nas*_*kew 70

设置不是那么简单

WindowStartupLocation="CenterScreen"
Run Code Online (Sandbox Code Playgroud)

在窗口的XAML定义中.

  • 这对于启动位置来说很好,但正如我在问题中指出的那样,当窗口改变大小时,我也希望在程序内执行此操作. (4认同)

Wil*_*d_A 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;
Run Code Online (Sandbox Code Playgroud)

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

  • 仅当您有1台显示器或所有显示器的大小相同时,此功能才有效 (6认同)

Jum*_*zza 15

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

  • Peter的方法是找到当前的监视器 - 而不仅仅是主监视器(严重的是谁只有1个监视器在工作了?)
  • @ Wild_A的方法是使用workarea而不是screen bounds考虑任务栏的空间.
  • 我不得不添加DPI缩放,专门用于显示1280x800的平板电脑为1024x640,但这对覆盖边缘情况非常有用,我在这里找到了答案.请注意,dpiScaling如果在显示UI之前首次加载时调用该变量,则该变量为null(在此处说明)
//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));
Run Code Online (Sandbox Code Playgroud)

其中,myWindowWidthmyWindowHeight是我用手动设置的窗口前面大小的变量.

  • 两个答案的完美结合,刚刚使用了这个,效果非常好。是的,我使用了 3 个屏幕 - 一个带有 Visual Studio,一个带有 pdf(电子书),一个带有 stackoverflow/outlook (2认同)
  • 这应该是明确的答案 (2认同)

小智 7

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

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;        
}
Run Code Online (Sandbox Code Playgroud)

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

this.Loaded += (s, a) => Globals.PostitionWindowOnScreen(this, 0, 0)
Run Code Online (Sandbox Code Playgroud)


小智 5

在window元素中只需添加此属性 - 值对: WindowStartupLocation ="CenterScreen"

  • "以编程方式,_not_在XAML中".无论如何,这不仅仅是对naskew答案的重复吗? (3认同)