WPF : How to set a Dialog position to show at the center of the application?

WpfDialog

Wpf Problem Overview


How to set Dialog's position that came from .ShowDialog(); to show at the center of the mainWindows.

This is the way I try to set position.

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

Wpf Solutions


Solution 1 - Wpf

In the XAML belonging to the Dialog:

<Window ... WindowStartupLocation="CenterOwner">

and in C# when you instantiate the Dialog:

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

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

Solution 2 - Wpf

I think it's easier to use xaml markup

<Window WindowStartupLocation="CenterOwner">

Solution 3 - Wpf

You can try to get a hold of the MainWindow in the Loaded event like this

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

Solution 4 - Wpf

Just in code behind.

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

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

Solution 5 - Wpf

I think everyone's answers to this question are parts to what the answer should be. I will simply put them together which I believe is the easiest and elegant approach to this problem.

First setup where you want the window to be located. Here it's the owner.

<Window WindowStartupLocation="CenterOwner">

Before opening the window we need to give it the owner and from another post we can access the MainWindow using the static getter for the current application's MainWindow.

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

That's it.

Solution 6 - Wpf

I found this one the best

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

Solution 7 - Wpf

If you have little control over the windows which you need to show, the following snippet may be useful

    public void ShowDialog(Window window)
    {
        Dispatcher.BeginInvoke(
            new Func<bool?>(() =>
            {
                window.Owner = Application.Current.MainWindow;
                window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                return window.ShowDialog();
            }));
    }

Solution 8 - Wpf

To get a WPF Dialog to position at the centre of a Windows Forms parent form I passed the parent form to the dialog since Application.Current didn't return the Windows Form parent (I assume it only works if the parent app is 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;
    }
}

set the WindowStartupLocation on the WPF Dialog:

<Window WindowStartupLocation="CenterParent">

and the way the Windows Form loads the WPF dialog is like this:

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

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

Solution 9 - Wpf

You must set a parent window to your window (Owner) and then set the WindowStartupLocation property to "CenterParent"

Solution 10 - Wpf

I'd like to add to the Fredrik Hedblad response that if the MainWindows has been resized or maximized, the result would be wrong, because mainWindow.Width and mainWindow.Height reflect the value that are set on the XAML.

If you want the actual values, you can use mainWindow.ActualWidth and 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;
    }

Solution 11 - Wpf

For the sake of documentation, I'll add here an example of how I achieved something similar. What I needed was a popup that covered the entire parent Window content area (excluding the title bar), but simply centering the dialog and stretching its content didn't work because the dialog was always offset a little bit from the bottom.

Note about user experience: It's not nice not being able to drag/close the parent window when the borderless dialog is showing, so I would reconsider using it. I also decided not to do this after posting this answer, but will leave it up for others to look at.

After some googling and testing, I finally managed to do it like this:

var dialog = new DialogWindow
{
    //this = MainWindow
    Owner = this
};
        
dialog.WindowStartupLocation = WindowStartupLocation.Manual;
dialog.WindowStyle = WindowStyle.None;
dialog.ShowInTaskbar = false;
dialog.ResizeMode = ResizeMode.NoResize;
dialog.AllowsTransparency = true;

var ownerContent = (FrameworkElement) Content;
dialog.MaxWidth = ownerContent.ActualWidth;
dialog.Width = ownerContent.ActualWidth;
dialog.MaxHeight = ownerContent.ActualHeight;
dialog.Height = ownerContent.ActualHeight;    

var contentPoints = ownerContent.PointToScreen(new Point(0, 0));
dialog.Left = contentPoints.X;
dialog.Top = contentPoints.Y;

dialog.ShowDialog();

The DialogWindow is a Window and its owner is set to the main application Window. The WindowStartupLocation must be set to Manual for manual positioning to work.

Result:

No dialog showing

Modal dialog showing

I don't know if there's an easier way to do this, but nothing else seemed to work for me.

Solution 12 - Wpf

XAML:

    <Window WindowStartupLocation="CenterScreen">

Solution 13 - Wpf

This code works if you don't want to use the WindowStartupLocation property in 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);
    }
}

I am using "screen.WorkingArea" because the task bar makes the mainWindow smaller. If you want to place the window in the middle of the screen, you can use "screen.Bounds" instead.

Solution 14 - Wpf

For the child window, set at the XAML

WindowStartupLocation="CenterOwner"

To call your child window as a dialog and center of the parent, call it from the parent window, e.g

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPrince OfThiefView Question on Stackoverflow
Solution 1 - WpfchesswebView Answer on Stackoverflow
Solution 2 - WpfThe SmallestView Answer on Stackoverflow
Solution 3 - WpfFredrik HedbladView Answer on Stackoverflow
Solution 4 - WpfRob DunbarView Answer on Stackoverflow
Solution 5 - WpfAlex EhlertView Answer on Stackoverflow
Solution 6 - WpfTim DavisView Answer on Stackoverflow
Solution 7 - WpfRahul MisraView Answer on Stackoverflow
Solution 8 - WpfJasonView Answer on Stackoverflow
Solution 9 - WpfUgo RobainView Answer on Stackoverflow
Solution 10 - WpfNicolò CarandiniView Answer on Stackoverflow
Solution 11 - WpfShahin DohanView Answer on Stackoverflow
Solution 12 - WpfGET1NEView Answer on Stackoverflow
Solution 13 - WpfMarkusView Answer on Stackoverflow
Solution 14 - Wpfsky91View Answer on Stackoverflow