Why does WindowStartupLocation = CenterScreen place my window somewhere other than the center of the screen?

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 associations) is 800 X 600.

When the window opens, 188, 141 (left, top) will appear. It is basically the "northwest" where it should be. If I calculate the truly centered values, it should be 240, 212 (left, top).

Key?

This is always the first window that has a problem. If I open a second instance of the same window, it will appear in the right place.

Another key?

The second instance of the window will only appear in the right place if I create both instances before opening the first.

So...

 Window win1 = windowFactory.CreateSplashWindow(); win1.Show(); Window win2 = windowFactory.CreateSplashWindow(); win2.Show(); win1.Hide(); 

... biases both win1 and win2

But...

 Window win1 = windowFactory.CreateSplashWindow(); Window win2 = windowFactory.CreateSplashWindow(); win1.Show(); win2.Show(); win1.Hide(); 

... biases win1 but shows win2 dead center.

So my question is:

What's going on here???




EDIT:

One more clue. If I add ...

 Width="800" Height="600" 

... in my Window declaration, the offset problem disappears. However, this is not a solution for me, because the window size must be saved in the settings file. That is why I have data binding in my style. (And note that binding data to width and height works fine - all windows are displayed as the correct size).




EDIT # 2:

I checked the width and height in debug mode and came to this interesting conclusion:

If I create several instances of the window, but do not open any windows, the Width and Height properties for all instances of the "NaN" window.

If I open only one of the instances, the width and height properties for each instance of the window are unexpectedly real numbers, not just the width and height of the window that I opened.

This tells me that WPF defers data binding until Show () is displayed in the first window.

β†’ So now the question is: can I get WPF to bind data before I show the first window?




Edit # 3:

I just submitted a bug report submitted by Microsoft in this release. Here's the link:

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

Edit # 4: Workaround

There is no real resolution 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 and the window you want in the center (FirstWindow).
  • Run the following code sequence:

...

 BlankWindow.Show() FirstWindow.Show() BlankWindow.Hide() 

XAML for my dummy window - nothing more:

 <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 do not see a noticeable flicker before "FirstWindow" opens, so I think this is a good enough solution until MS starts to fix the error.

+11
wpf xaml
Jul 26 '09 at 21:49
source share
4 answers

Can your Width and Height bindings interfere? If you don't set Width and Height , does the window appear in the right place? If so, is this the same place as when you have the bindings set above?

If all this is true, then it looks like WPF calculates the window layout before getting the Width and Height values ​​from your bindings. I'm not sure of a good way around this - maybe first set Width and Height manually (either in XAML or in the constructor), and then adjust the bindings after displaying it?

+4
Jul 26 '09 at 23:37
source share

I do not see field references in your examples. However, I am often disappointed when Visual Studio changes the margins for elements (when they are in the grid) after dragging the side of the object in the constructor (I would think that this will change its width, not its margin). And, having weird fields, unforeseen placement problems may occur.

0
Jul 31 '09 at 0:36
source share

This is a pretty old post, but since I could not find the right solution, I have one more job: You can calculate the location of your dialog manually ( http://social.msdn.microsoft.com/Forums/eu/wpf/thread/054800c3 -56dc-4700-a2fb-d2b79fc9ef9a ).

Not very elegant, but it works:

 public class Controller { private Double CalcCoordinate(Double parentCoordinate, Double parentSize, Double thisSize) { return parentCoordinate + (parentSize - thisSize) / 2; } public Controller(Double width, Double height, Window owner) { Width = width; Height = height; Left = CalcCoordinate(owner.Left, owner.Width, Width); Top = CalcCoordinate(owner.Top, owner.Height, Height); } public Double Width { get; set; } public Double Height { get; set; } public Double Left { get; set; } public Double Top { get; set; } 

}

Then just bind the location and size of the window to these properties and remember to change WindowStartupLocation to Manual.

For some reason I just don't get it, Top / Left should be tied in TwoWay mode, I could not get it to work correctly without it.

0
Sep 16 '12 at 13:32
source share

Another workaround ... add the return value to the bindings.

 Width="{Binding Width, FallbackValue=500}" Height="{Binding Height, FallbackValue=500}" 
0
Nov 07 '17 at 16:10
source share



All Articles