Here's the Window declaration:
<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">
Here's the Style declaration:
<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>
Discussion:
The screen is 1280 X 1024. The window size (determined by the InitialWindowWidth, InitialWindowHeight bindings) is 800 X 600.
When the Window opens, it appears 188, 141 (left, top). This is basically "northwest" of where it should be. If I calculate the true centered values, it should be 240, 212 (left, top).
A clue?
It's always the first window that has the problem. If I open a second instance of the same window, it will show up in the correct location.
Another clue?
The second window instance will only show up in the correct location if I create both instances before opening the first one.
So...
Window win1 = windowFactory.CreateSplashWindow();
win1.Show();
Window win2 = windowFactory.CreateSplashWindow();
win2.Show();
win1.Hide();
...offsets both win1 and win2
But...
Window win1 = windowFactory.CreateSplashWindow();
Window win2 = windowFactory.CreateSplashWindow();
win1.Show();
win2.Show();
win1.Hide();
...offsets win1 but shows win2 dead center.
So my question is:
What is going on here???
EDIT:
Yet another clue. If I add...
Width="800"
Height="600"
...to my Window declaration, the offset problem disappears. This isn't a solution for me, though, because I need the window size to be a preference stored in a settings file. That's why I have the data binding in my Style. (And note, the data binding for the Width and Height works fine--all windows show up as the correct size).
EDIT #2:
I did checking of widths and heights while in debug mode and came to this interesting conclusion:
If I create multiple window instances but don't open any windows, the Width and Height properties of all window instances are "NaN".
If I then open just one of the instances, the width and height properties of all window instance are suddenly valid numbers, not just the width and height of the window I opened.
This tells me that WPF defers data-binding until Show() is called on the first window.
--> So now the question becomes: Can I force WPF to do the data-binding before I show the first window?
Edit #3:
I just submitted submitted a bug report on this issue to Microsoft. Here is the link:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=477598
Edit #4: A Workaround
No real resolution on this yet, but I just confirmed that you can work around the problem using a dummy window. Follow these steps:
- Create a new XPF Window called "BlankWindow" (see XAML below).
- Create an instance of BlankWindow plus the window you'd like to be centered on the screen (FirstWindow).
- Execute the following code sequence:
...
BlankWindow.Show()
FirstWindow.Show()
BlankWindow.Hide()
The XAML for my dummy window is nothing more than this:
<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>
I see no noticeable flicker before "FirstWindow" opens, so I consider it a good enough workaround until MS get around to fixing the bug.