WPF : How to set a Dialog position to show at the

2020-02-02 08:41发布

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 dialog
14条回答
成全新的幸福
2楼-- · 2020-02-02 08:57

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.

查看更多
叛逆
3楼-- · 2020-02-02 08:59

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();
            }));
    }
查看更多
来,给爷笑一个
4楼-- · 2020-02-02 09:00

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.

查看更多
地球回转人心会变
5楼-- · 2020-02-02 09:01

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)
{
    ...
查看更多
劫难
6楼-- · 2020-02-02 09:01

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;
    }
查看更多
SAY GOODBYE
7楼-- · 2020-02-02 09:05

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;
}
查看更多
登录 后发表回答