WPF: Как установить позицию диалога для отображения в центре приложения?


Как установить позицию диалога, которая пришла из .ShowDialog(); для отображения в центре главного окна.

вот как я пытаюсь установить положение.

private void Window_Loaded(object sender, RoutedEventArgs e)
{        
    PresentationSource source = PresentationSource.FromVisual(this);
    if (source != null)
    {
        Left = ??
        Top = ??
    }
}
12 66

12 ответов:

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

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Application curApp = Application.Current;
    Window mainWindow = curApp.MainWindow;
    this.Left = mainWindow.Left + (mainWindow.Width - this.ActualWidth) / 2;
    this.Top = mainWindow.Top + (mainWindow.Height - this.ActualHeight) / 2;
}

в XAML, принадлежащем диалоговому окну:

<Window ... WindowStartupLocation="CenterOwner">

и в C# при создании диалога:

MyDlg dlg = new MyDlg();
dlg.Owner = this;

if (dlg.ShowDialog() == true)
{
    ...

Я думаю, что проще использовать разметку xaml

<Window WindowStartupLocation="CenterParent">

просто в коде.

public partial class CenteredWindow:Window
{
    public CenteredWindow()
    {
        InitializeComponent();

        WindowStartupLocation = WindowStartupLocation.CenterOwner;
        Owner = Application.Current.MainWindow;
    }
}

Я думаю, что ответы каждого на этот вопрос являются частью того, каким должен быть ответ. Я просто сложу их вместе, что я считаю самым простым и элегантным подходом к этой проблеме.

первая настройка, где вы хотите, чтобы окно было расположено. Вот он, хозяин.

<Window WindowStartupLocation="CenterOwner">

перед открытием окна нам нужно дать его владельцу, а из другого сообщения мы можем получить доступ к главному окну, используя статический геттер для текущего приложения Главное окно.

        Window window = new Window();
        window.Owner = Application.Current.MainWindow;
        window.Show();

вот именно.

Я нашел этот самый лучший

frmSample fs = new frmSample();
fs.Owner = this; // <-----
fs.WindowStartupLocation = WindowStartupLocation.CenterOwner;
var result = fs.ShowDialog();

чтобы получить диалоговое окно WPF для размещения в центре родительской формы Windows Forms, я передал родительскую форму в диалоговое окно с момента приложения.Current не возвращает родительскую форму Windows (я предполагаю, что она работает только в том случае, если родительское приложение является WPF).

public partial class DialogView : Window
{
    private readonly System.Windows.Forms.Form _parent;

    public DialogView(System.Windows.Forms.Form parent)
    {
        InitializeComponent();

        _parent = parent;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        this.Left = _parent.Left + (_parent.Width - this.ActualWidth) / 2;
        this.Top = _parent.Top + (_parent.Height - this.ActualHeight) / 2;
    }
}

установите WindowStartupLocation в диалоговом окне WPF:

<Window WindowStartupLocation="CenterParent">

и то, как форма Windows загружает диалоговое окно WPF, выглядит следующим образом:

DialogView dlg = new DialogView();
dlg.Owner = this;

if (dlg.ShowDialog() == true)
{
    ...

вы должны установить родительское окно для вашего окна (владельца), а затем установить WindowStartupLocation свойство "CenterParent"

Я хотел бы добавить к ответу Фредрика Хедблада, что если MainWindows был изменен или максимизирован, результат будет неправильным, потому что mainWindow.Ширина и главное окно.Высота отражает значение, заданное в XAML.

Если вы хотите фактические значения, вы можете использовать mainWindow.ActualWidth и mainWindow.ActualHeight:

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Application curApp = Application.Current;
        Window mainWindow = curApp.MainWindow;
        this.Left = mainWindow.Left + (mainWindow.ActualWidth - this.ActualWidth) / 2;
        this.Top = mainWindow.Top + (mainWindow.ActualHeight - this.ActualHeight) / 2;
    }

XAML:

    <Window WindowStartupLocation="CenterScreen">

этот код работает, если вы не хотите использовать свойство WindowStartupLocation в xaml:

private void CenterWindowOnApplication()
{
    System.Windows.Application curApp = System.Windows.Application.Current;
    Window mainWindow = curApp.MainWindow;
    if (mainWindow.WindowState == WindowState.Maximized)
    {
        // Get the mainWindow's screen:
        var screen = System.Windows.Forms.Screen.FromRectangle(new System.Drawing.Rectangle((int)mainWindow.Left, (int)mainWindow.Top, (int)mainWindow.Width, (int)mainWindow.Height));
        double screenWidth = screen.WorkingArea.Width;
        double screenHeight = screen.WorkingArea.Height;
        double popupwindowWidth = this.Width;
        double popupwindowHeight = this.Height;
        this.Left = (screenWidth / 2) - (popupwindowWidth / 2);
        this.Top = (screenHeight / 2) - (popupwindowHeight / 2);
    }
    else
    {
        this.Left = mainWindow.Left + ((mainWindow.ActualWidth - this.ActualWidth) / 2;
        this.Top = mainWindow.Top + ((mainWindow.ActualHeight - this.ActualHeight) / 2);
    }
}

Я использую "экран.WorkingArea", потому что панель задач делает mainWindow меньше. Если вы хотите разместить окно в середине экрана, вы можете использовать "экран.Границы" вместо этого.

для дочернего окна установите в XAML

WindowStartupLocation="CenterOwner"

чтобы вызвать дочернее окно в качестве диалогового окна и Центра родителя, вызовите его из родительского окна, например

private void ConfigButton_OnClick(object sender, RoutedEventArgs e)
{
    var window = new ConfigurationWindow
    {
        Owner = this
    };
    window.ShowDialog();
}