欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

WPF 解决Popup的位置不能随窗口位置、大小改变而改变的问题

程序员文章站 2022-05-22 19:05:06
...

问题描述:WPF中会使用Popup来实现类似点击按钮,弹出一个小下拉窗口(非window)的功能。如果popup设置了StayOpen,此时改变窗口的大小或者位置,会发现Popup停在原地,不会随着窗口的位置、大小变化而改变。类似下图:
WPF 解决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的LocationChangedSizeChanged事件中改变Popup的HorizontalOffset属性。

private void MainWindow_LocationChanged(object sender, EventArgs e)
{
    double offset = popup.HorizontalOffset;
    popup.HorizontalOffset = offset + 1;
    popup.HorizontalOffset = offset;
}

相比其他方法要简单很多。但是看了半天没明白啥意思,欢迎交流。

  1. 实际测试时,如果不加后两句,实时看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());
}

WPF 解决Popup的位置不能随窗口位置、大小改变而改变的问题

  1. 所以接着理解第二句,第二句的offse+1其实加减多少无所谓,小一点的话移动位置时人眼看的不明显。我觉得是强行改变HorizontalOffset使其不为0,然后第三句再设置成0,也就是第一句获得的offse,也就实现了Popup位置的移动。但是还是有点牵强的感觉,欢迎交流。

(多说一句,为什么WPF内部不实现popup自动更新位置呢,不然设置PlacementTarget的意义好像不太大了)

相关标签: WPF c#