WPF WindowStartupLocation="CenterOwner" 不是真正居中,并且到处弹出,为什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3452854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:00:39  来源:igfitidea点击:

WPF WindowStartupLocation="CenterOwner" not really center, and pops all over, why?

wpf

提问by nportelli

Well thisquestion and thisquestion are similar but no answers that work. In fact I was hoping WindowStartupLocation=CenterOwner would work...it doesn't. It seems to center the new window in the center of a grid column, not the center of the main window. So I'm assuming it thinks that is the parent. Second when I close the dialog and open it again it is not centered but moved down and right from the previous position. And if I move the main window to a second monitor the popup still opens on the default monitor. Are these properties wrong or am I just thinking it should work in a different way. I suppose I could calculate the Top and Left properties manually. I just want the popup to be centered in the main window no matter where it is.

那么这个问题和这个问题是相似的,但没有有效的答案。事实上,我希望 WindowStartupLocation=CenterOwner 会起作用……它不会。它似乎将新窗口置于网格列的中心,而不是主窗口的中心。所以我假设它认为这是父母。其次,当我关闭对话框并再次打开它时,它不是居中而是从之前的位置向下和向右移动。如果我将主窗口移动到第二个监视器,弹出窗口仍会在默认监视器上打开。这些属性是错误的还是我只是认为它应该以不同的方式工作。我想我可以手动计算 Top 和 Left 属性。我只希望弹出窗口无论在何处都位于主窗口的中心。

回答by Carlo

Probably because you didn't set the owner:

可能是因为你没有设置所有者:

this.Owner = App.MainWindow; // for example

That's how I do it and it centers the window perfectly all the time.

我就是这样做的,它始终将窗口完美地居中。

To extend on what Will Eddins commented, you could create an overload method for ShowDialog() or Show() in your Window:

为了扩展 Will Eddins 的评论,您可以在窗口中为 ShowDialog() 或 Show() 创建一个重载方法:

public void ShowDialog(Window owner)
{
    this.Owner = owner;
    this.ShowDialog();
}

public void Show(Window owner)
{
    this.Owner = owner;
    this.Show();
}

Or overload a constructor:

或者重载一个构造函数:

public MyWindow(Window owner)
    : this()
{
    this.Owner = owner;
}

回答by Elken

If you create an extention for this, you could reuse this fine idea:

如果您为此创建扩展,您可以重用这个好主意:

/// <summary>
/// Opens a window modally, with an owner
/// </summary>
/// <param name="window">The window to open</param>
/// <param name="opener">The owner of the window getting opened</param>
/// <returns>window.ShowDialog()</returns>
public static bool? ShowDialog(this Window window, Window opener)
{
    window.Owner = opener;
    return window.ShowDialog();
}

回答by kenkenes

I had the same problem...but it was mostly due to the fact that, when i wanted to get rid of the child window, I used hide()instead of close()... so when you reopen it, because it was hidden and not closed, when the parent window is moved, it still opens at it's startup location...

我遇到了同样的问题......但主要是因为当我想摆脱子窗口时,我使用了hide()而不是close()......所以当你重新打开它时,因为它被隐藏而不是关闭,当父窗口被移动时,它仍然在它的启动位置打开......

So when close the child window instead of hiding it for example when finished working with it.

因此,当关闭子窗口而不是隐藏它时,例如在完成工作时。

回答by Dan

Something else that can cause this is setting DataContextafter InitializeComponent()is called.

其他可能导致这种情况的原因是DataContextInitializeComponent()调用之后设置。

If you have code-behind like this:

如果你有这样的代码隐藏:

    public CustomWindow(CustomViewModel viewModel)
    {
        InitializeComponent();
        DataContext = viewModel;
    }

Change it to:

将其更改为:

    public CustomWindow(CustomViewModel viewModel)
    {
        DataContext = viewModel;
        InitializeComponent();
    }