WPF 解决Popup的位置不能随窗口位置、大小改变而改变的问题
程序员文章站
2022-05-22 19:05:06
...
问题描述:WPF中会使用Popup来实现类似点击按钮,弹出一个小下拉窗口(非window)的功能。如果popup设置了StayOpen,此时改变窗口的大小或者位置,会发现Popup停在原地,不会随着窗口的位置、大小变化而改变。类似下图:
布局代码:
<Border BorderBrush="Black" BorderThickness="1" Margin="100,150">
<Grid>
<Button Name="btn" Content="下拉框停靠位置" Width="100" Height="50"/>
<Popup Name="popup" IsOpen="True" StaysOpen="True"
AllowsTransparency="True"
PlacementTarget="{Binding ElementName=btn}">
<TextBlock Text="这是一个popup"/>
</Popup>
</Grid>
</Border>
为了演示效果,IsOpen和StayOpen都设置成True。
解决方法:网上很多解决方法都是写一个附加属性,例如博客等等。感觉挺麻烦的。后来无意间找到了一个很简洁的解决方法,参考博客。
直接在MainWindow的LocationChanged
和SizeChanged
事件中改变Popup的HorizontalOffset
属性。
private void MainWindow_LocationChanged(object sender, EventArgs e)
{
double offset = popup.HorizontalOffset;
popup.HorizontalOffset = offset + 1;
popup.HorizontalOffset = offset;
}
相比其他方法要简单很多。但是看了半天没明白啥意思,欢迎交流。
- 实际测试时,如果不加后两句,实时看
HorizontalOffset
一直都是0,也就是说移动窗口,但是Popup停留在原地,此时HorizontalOffset
还是0,就有点奇怪了。按理来说不应该会改变吗?
private void MainWindow_LocationChanged(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("1: " + popup.HorizontalOffset.ToString());
double offset = popup.HorizontalOffset;
//popup.HorizontalOffset = offset + 1;
//popup.HorizontalOffset = offset;
System.Diagnostics.Debug.WriteLine("2: " + popup.HorizontalOffset.ToString());
}
- 所以接着理解第二句,第二句的
offse+1
其实加减多少无所谓,小一点的话移动位置时人眼看的不明显。我觉得是强行改变HorizontalOffset
使其不为0,然后第三句再设置成0,也就是第一句获得的offse
,也就实现了Popup位置的移动。但是还是有点牵强的感觉,欢迎交流。
(多说一句,为什么WPF内部不实现popup自动更新位置呢,不然设置PlacementTarget
的意义好像不太大了)