Как центрировать главное окно в WPF?
У меня есть приложение WPF, и мне нужно знать, как программно центрировать окно wain (не в XAML).
Мне нужно иметь возможность делать это как при запуске, так и в ответ на определенные события пользователя. Он должен быть динамически рассчитан, так как сам размер окна является динамическим.
какой самый простой способ сделать это? В старом коде Win32 я бы вызвал функции системных метрик и все это разработал. Это все еще так, как это делается, или есть простой CenterWindowOnScreen()
функция, которую я теперь могу вызвать.
10 ответов
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);
}
этот метод можно использовать для установки положения окна в центре экрана.
Ну, для времени запуска вы можете установить автозагрузки:
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
позже вам нужно будет запросить его. Информация (по крайней мере для основного экрана) доступна через SystemParameters.PrimaryScreenWidth/Высота.
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
)
мне пришлось объединить несколько из этих ответов, чтобы покрыть все основания в моем случае:
- Петровская чтобы найти текущий монитор-а не только основной монитор (серьезно, кто имеет только 1 монитор на работе больше?)
- @Wild_A это!--11--> использовать
workarea
, а неscreen bounds
чтобы учесть пространство для панели задач. - мне пришлось добавить масштабирование DPI, специально для планшета, отображающего 1280x800 как 1024x640, но который полезен для покрытия краевых случаев, для которых я нашел ответ для здесь. Примечание
dpiScaling
переменная имеет значение 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));
здесь myWindowWidth
и myWindowHeight
являются переменными, которые я использовал для ручной установки размера окна ранее.
в случае, если вам нужно нарисовать окно в среде с несколькими экранами. Я создал статический класс, в котором можно повторно использовать следующий метод:
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;
}
в конструкторе окна теперь просто вызываем метод:
this.Loaded += (s, a) => Globals.PostitionWindowOnScreen(this, 0, 0)
в качестве базового решения можно использовать свойство StartupLocation окна, присвоив ему одно из значений перечисления, определенных в System.Окна.Перечисление WindowStartupLocation, есть один для центра экрана:
_wpfWindow.StartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
к сожалению, это не всегда так просто; вам нужно учитывать несколько мониторов,панелей задач и т. д. Опция "CenterScreen" открывает окно в центре экрана с курсором мыши. См.это так вопрос для многих информация или ссылка на api.
Если вы его развернуть сразу
этот.Windowstate Значение = Система.Окна.Windowstate значение.Максимизировано;
на основе ответа @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; }
}