为什么WindowStartupLocation = CenterScreen将我的窗口放在除屏幕中心之外的某个位置?

dev*_*xer 12 wpf xaml

这是窗口声明:

<Window
    x:Class="Pse.ExperimentBase.SplashWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Style="{StaticResource _windowStyle}"
    WindowStartupLocation="CenterScreen"
    WindowStyle="None">
Run Code Online (Sandbox Code Playgroud)

这是样式声明:

<Style
    x:Key="_windowStyle"
    TargetType="Window">
    <Setter
        Property="Width"
        Value="{Binding Path=InitialWindowWidth}" />
    <Setter
        Property="Height"
        Value="{Binding Path=InitialWindowHeight}" />
    <Setter
        Property="Icon"
        Value="Resources/MyIcon.ico" />
    <Setter
        Property="Background"
        Value="{StaticResource _fadedOrangeBrush}" />
    <Setter
        Property="FontSize"
        Value="11" />
</Style>
Run Code Online (Sandbox Code Playgroud)

讨论:

屏幕为1280 X 1024.窗口大小(由InitialWindowWidth,InitialWindowHeight绑定确定)为800 X 600.

窗口打开时,它显示188,141(左,上).这基本上应该是"西北".如果我计算真正的居中值,它应该是240,212(左,上).

线索?

它始终是第一个出现问题的窗口.如果我打开同一窗口的第二个实例,它将显示在正确的位置.

另一个线索?

如果我在打开第一个实例之前创建两个实例,则第二个窗口实例将显示在正确的位置.

所以...

Window win1 = windowFactory.CreateSplashWindow();
win1.Show();
Window win2 = windowFactory.CreateSplashWindow();
win2.Show();
win1.Hide();
Run Code Online (Sandbox Code Playgroud)

...抵消win1和win2

但...

Window win1 = windowFactory.CreateSplashWindow();
Window win2 = windowFactory.CreateSplashWindow();
win1.Show();
win2.Show();
win1.Hide();
Run Code Online (Sandbox Code Playgroud)

...抵消win1,但显示win2死亡中心.

所以我的问题是:

这里发生了什么???


编辑:

又一个线索.如果我添加......

Width="800"
Height="600"
Run Code Online (Sandbox Code Playgroud)

...到我的Window声明,偏移问题消失了.但这不是我的解决方案,因为我需要将窗口大小作为首选项存储在设置文件中.这就是我在我的Style中有数据绑定的原因.(请注意,Width和Height的数据绑定工作正常 - 所有窗口都显示为正确的大小).


编辑#2:

我在调试模式下检查了宽度和高度,得出了这个有趣的结论:

如果我创建多个窗口实例但不打开任何窗口,则所有窗口实例的"宽度"和"高度"属性都是"NaN".

如果我然后只打开其中一个实例,所有窗口实例的宽度和高度属性都是突然有效的数字,而不仅仅是我打开的窗口的宽度和高度.

这告诉我WPF推迟数据绑定,直到在第一个窗口上调用Show().

- >所以现在问题变成了:显示第一个窗口之前,我可以强制WPF进行数据绑定吗?


编辑#3:

我刚刚向Microsoft提交了有关此问题的错误报告.链接在这里:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=477598

编辑#4:一种解决方法

目前还没有真正的解决方案,但我刚刚确认您可以使用虚拟窗口解决问题.跟着这些步骤:

  1. 创建一个名为"BlankWindow"的新XPF窗口(参见下面的XAML).
  2. 创建BlankWindow的实例以及您希望在屏幕上居中的窗口(FirstWindow).
  3. 执行以下代码序列:

...

BlankWindow.Show()
FirstWindow.Show()
BlankWindow.Hide()
Run Code Online (Sandbox Code Playgroud)

我的虚拟窗口的XAML只不过是这样的:

<Window
    x:Class="Pse.ExperimentBase.Windows.BlankWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="BlankWindow"
    Height="0"
    Width="0"
    WindowStyle="None">
    <Grid></Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

在"FirstWindow"打开之前我没有看到明显的闪烁,所以我认为这是一个足够好的解决方法,直到MS开始修复bug.

And*_*ndy 4

您的WidthHeight绑定会妨碍吗?如果您根本不设置WidthHeight,窗口是否会出现在正确的位置?如果是这样,该位置是否与您按上述方式设置绑定时的位置相同?

如果所有这些都是真的,那么听起来 WPF 正在计算窗口的位置,然后再获取绑定的WidthHeight。我不确定解决这个问题的好方法 - 也许首先设置WidthHeight手动(在 XAML 或构造函数中),然后在显示后设置绑定?