WPF:如何设置对话框位置以显示在应用程序的中心?


83

如何设置Dialog的位置,该位置 .ShowDialog();显示在mainWindows的中心。

这是我尝试设置位置的方法。

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

Answers:


35

您可以像这样尝试在Loaded事件中保留MainWindow

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

8
这会将左上角放在中心。这个没有被接受的答案更准确地实现了OP的愿望。
克里斯·希夫豪尔

277

在属于该对话框的XAML中:

<Window ... WindowStartupLocation="CenterOwner">

并在C#中实例化对话框:

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

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

17
实际上可以var dlg = new MyDlg { Owner = this };在第二位上做。
Jodrell 2012年

6
如果您使用的是MVVM模式,则可以使用它来查找所有者:dlg.Owner = Application.Current.MainWindow;
Jakob BuskSørensen,

55

我认为使用xaml标记更容易

<Window WindowStartupLocation="CenterOwner">

不,我不能使用它,因为父级不是主窗口
Thief

6
您可以通过设置Window.Owner来使任何窗口成为所有者。
2012年

10
mmmCenterParent还是CenterOwner?我只CenterOwner在Intellisense中看到
Brock Hensley

@dirt可能取决于您使用的WPF版本。
BrainSlugs83

WPF和WinForms的CenterOwner和CenterParent分别不同
F8ER

21

只是在后面的代码中。

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

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

19

我认为每个人对这个问题的答案都是答案的一部分。我将把它们放在一起,我认为这是解决此问题的最简单,最优雅的方法。

首先设置您要放置窗口的位置。这是所有者。

<Window WindowStartupLocation="CenterOwner">

在打开窗口之前,我们需要为它提供所有者,并且在其他帖子中,我们可以使用静态吸气剂访问当前应用程序MainWindow的MainWindow。

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

而已。


1
中心父级不存在,在这种情况下,WindowStartupLocation应为CenterOwner。
乌帕

1
谢谢你让我知道。不知道为什么我放CenterParent。它已被更改。
Alex Ehlert

1
我不知道为什么这种解决方案不被接受,这是避免计算麻烦的原因,而WPF则将其作为开箱即用的解决方案...
cdie

2
这是最好的解决方案。
Beyondo

1
在滚动到此答案之前,我最终正是这样做了。+1提高知名度!
亚历克西斯·勒克莱尔

8

我发现这是最好的

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

5

如果您几乎无法控制需要显示的窗口,则以下代码段可能会有用

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

我不知道为什么这没有太多投票。对我来说,这是应该做的。对于中心所有者,您必须分配所有者,然后它才能正常工作。
VPZ

3

为了将WPF对话框放置在Windows Forms父窗体的中心,我将父窗体传递给对话框,因为Application.Current不会返回Windows Form父窗体(我假设只有在父应用程序是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;
    }
}

在WPF对话框上设置WindowStartupLocation:

<Window WindowStartupLocation="CenterParent">

Windows窗体加载WPF对话框的方式如下:

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

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

2

您必须将一个父窗口设置为您的窗口(所有者),然后将WindowStartupLocation属性设置为“ CenterParent”


2
确实,在WPF中,该属性称为“ CenterOwner”,而不是“ CenterParent”。
Beta

2

我想在Fredrik Hedblad响应中添加一个内容,即如果MainWindows已调整大小或最大化,结果将是错误的,因为mainWindow.Width和mainWindow.Height反映了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;
    }

1

XAML:

    <Window WindowStartupLocation="CenterScreen">

0

如果您不想在xaml中使用WindowStartupLocation属性,则此代码有效:

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

我正在使用“ screen.WorkingArea”,因为任务栏使mainWindow变小了。如果要将窗口放置在屏幕中间,则可以改用“ screen.Bounds”。


0

对于子窗口,在XAML处进行设置

WindowStartupLocation="CenterOwner"

要将子窗口称为对话框并作为父窗口的中心,请从父窗口调用它,例如

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

0

为了便于说明,我将在此处添加一个示例,说明如何实现类似目的。我需要的是一个弹出窗口,该弹出窗口覆盖了整个父窗口内容区域(标题栏除外),但是仅使对话框居中并拉伸其内容是行不通的,因为该对话框总是从底部偏移一点。

关于用户体验的注意事项:当显示无边界对话框时,无法拖动/关闭父窗口是不好的,所以我会重新考虑使用它。发布此答案后,我还决定不执行此操作,但将其留给其他人查看。

经过一些谷歌搜索和测试之后,我终于设法做到了:

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();

DialogWindow是一个窗口,它的主人被设置到应用程序主窗口。的WindowStartupLocation必须设置为Manual手动定位的工作。

结果:

没有对话框显示

模态对话框显示

我不知道是否有更简单的方法可以执行此操作,但是似乎没有其他方法适合我。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.