这是窗口声明:
<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">
这是样式声明:
<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>
讨论:
屏幕为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();
...抵消win1和win2
但是...
Window win1 = windowFactory.CreateSplashWindow();
Window win2 = windowFactory.CreateSplashWindow();
win1.Show();
win2.Show();
win1.Hide();
...抵消win1,但显示win2死亡中心。
所以我的问题是:
这里发生了什么???
修改
又一条线索。如果我添加......
Width="800"
Height="600"
...到我的Window声明,偏移问题消失了。但这不是我的解决方案,因为我需要将窗口大小作为首选项存储在设置文件中。这就是我在我的Style中有数据绑定的原因。 (请注意,Width和Height的数据绑定工作正常 - 所有窗口都显示为正确的大小。)
编辑#2:
我在调试模式下检查了宽度和高度,得出了这个有趣的结论:
如果我创建了多个窗口实例但没有打开任何窗口,则所有窗口实例的“宽度”和“高度”属性都是“NaN”。
如果我然后只打开一个实例,所有窗口实例的宽度和高度属性都是突然有效的数字,而不仅仅是窗口的宽度和高度我打开了。
这告诉我WPF推迟数据绑定,直到在第一个窗口调用Show()。
- &gt; 现在问题变成了:我可以强制WPF在显示第一个窗口之前进行数据绑定吗?
编辑#3:
我刚刚向Microsoft提交了有关此问题的错误报告。这是链接:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=477598
编辑#4:解决方法
目前还没有真正的解决方案,但我刚刚确认您可以使用虚拟窗口解决问题。请按照以下步骤操作:
...
BlankWindow.Show()
FirstWindow.Show()
BlankWindow.Hide()
我的虚拟窗口的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>
在“FirstWindow”打开之前我没有看到明显的闪烁,所以我认为这是一个足够好的解决方法,直到MS开始修复bug。
答案 0 :(得分:4)
你的Width
和Height
绑定会妨碍你吗?如果您根本没有设置Width
和Height
,窗口是否显示在正确的位置?如果是这样,那个位置是否与上面设置的绑定相同?
如果一切正确,那么听起来WPF在从绑定中获取Width
和Height
的值之前计算窗口的位置。我不确定解决这个问题的好方法 - 可能首先手动设置Width
和Height
(在XAML或构造函数中),然后在显示绑定后设置它?
答案 1 :(得分:1)
另一种解决方法......为绑定添加一个后备值。
Width="{Binding Width, FallbackValue=500}" Height="{Binding Height, FallbackValue=500}"
答案 2 :(得分:0)
我的示例中没有看到任何对Margins的引用。但是,当Visual Studio在设计器中拖动对象的一侧后更改项目的边距(当它们在网格中时)时,我常常感到沮丧(我认为它会改变它的宽度,而不是它的边距)。并且,有奇怪的边距会导致意外的放置问题。
答案 3 :(得分:0)
这是相当古老的帖子,但由于我找不到任何合适的解决方案,我还有另一个解决办法: 您可以手动计算对话框的位置(http://social.msdn.microsoft.com/Forums/eu/wpf/thread/054800c3-56dc-4700-a2fb-d2b79fc9ef9a)。
不是很优雅,但它有效:
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; }
}
然后,只需将窗口的位置和大小绑定到这些属性,并且不要忘记将WindowStartupLocation更改为Manual。
出于某种原因,我只是没有得到,顶部/左侧必须以双向模式绑定,没有它我无法正常工作。