Как вы центрируете свое главное окно в WPF? - PullRequest
50 голосов
/ 26 октября 2010

У меня есть приложение WPF, и мне нужно знать, как программно центрировать окно Wain (не в XAML).

Мне нужно иметь возможность делать это как при запуске, так и в ответ на определенные пользовательские события,Он должен быть рассчитан динамически, поскольку сам размер окна является динамическим.

Какой самый простой способ сделать это?При старом коде Win32 я бы вызывал функции метрик системы и все это решал.Это все еще так, как это делается, или есть простая CenterWindowOnScreen() функция, которую я теперь могу вызвать.

Ответы [ 11 ]

93 голосов
/ 26 октября 2010

Ну, для времени запуска вы можете установить место запуска :

window.WindowStartupLocation = WindowStartupLocation.CenterScreen;

Позже вам нужно будет запросить его.Информация (по крайней мере, для основного экрана) доступна через SystemParameters.PrimaryScreenWidth / Height.

74 голосов
/ 26 октября 2010
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);
}

Вы можете использовать этот метод для установки положения окна в центр экрана.

67 голосов
/ 28 августа 2013

Разве не так просто установить

WindowStartupLocation="CenterScreen"

В определении XAML для окна.

22 голосов
/ 15 января 2013
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.Left и workArea.Top)

13 голосов
/ 16 сентября 2015

Мне пришлось объединить несколько из этих ответов, чтобы охватить все основы в моем случае:

  • Метод Питера , чтобы найти текущий монитор, а не только основной монитор (серьезно, у кого больше только один монитор на работе?)
  • @ Метод Wild_A для использования workarea вместо screen bounds для учета пространства для панели задач.
  • Мне пришлось добавить масштабирование DPI, особенно для планшета, отображающего 1280x800 как 1024x640, но который полезен для покрытия крайних случаев, для которых я нашел ответ для здесь . Обратите внимание, что переменная dpiScaling равна нулю, если вызывается при первой загрузке до отображения пользовательского интерфейса ( объяснено здесь )
//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));

, где myWindowWidth и myWindowHeight - переменные, которые я использовал для ручной установки размера окна ранее.

5 голосов
/ 27 августа 2014

В случае, если вам нужно нарисовать окно в многоэкранной среде. Я создал статический класс, в котором можно повторно использовать следующий метод:

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)
5 голосов
/ 21 марта 2014

В элементе окна просто добавьте эту пару атрибут-значение: WindowStartupLocation = "CenterScreen"

4 голосов
/ 26 октября 2010

В качестве базового решения вы можете использовать свойство StartupLocation окна, установить для него одно из значений перечисления, определенных в перечислении System.Windows.WindowStartupLocation, для центра экрана есть одно:

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

К сожалению, это не всегда так просто; вам необходимо учитывать несколько мониторов, панелей задач и т. д. Опция «CenterScreen» открывает окно в центре экрана, на котором находится курсор мыши. См. этот SO вопрос для получения дополнительной информации или ссылку на api .

0 голосов
/ 18 июня 2019

Перейти к окну свойств MainWindow.xaml

  • найти WindowStartupLocation свойство из общей категории
  • выбрать CenterScreen опция из выпадающего меню
  • Запустить приложение

для полноэкранного режима

Перейти в окно свойств MainWindow.xaml

  • найти WindowState свойство из общей категории
  • выберите развернуто вариант из выпадающего списка
  • Запустите приложение
0 голосов
/ 15 апреля 2016

На основании ответа @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; }
}
...