【发布时间】:2011-11-10 23:05:08
【问题描述】:
我正在使用 WPF Popup 控件。我希望它出现在我的应用程序窗口中,固定在窗口的右下角。弹出窗口的实际高度和宽度将根据正在显示的消息而变化。
如果重要的话,弹出的内容是一个Border,包装一个StackPanel,包含多个TextBlock。
感谢您的帮助。
【问题讨论】:
标签: wpf
我正在使用 WPF Popup 控件。我希望它出现在我的应用程序窗口中,固定在窗口的右下角。弹出窗口的实际高度和宽度将根据正在显示的消息而变化。
如果重要的话,弹出的内容是一个Border,包装一个StackPanel,包含多个TextBlock。
感谢您的帮助。
【问题讨论】:
标签: wpf
使用 PlacementTarget,Placement=Left,Horizontal/VerticalOffset
<Popup IsOpen="{Binding ElementName=togglebutton, Path=IsChecked, Mode=TwoWay}"
PlacementTarget="{Binding ElementName=togglebutton}"
Placement="Left"
HorizontalOffset="{Binding ActualWidth, ElementName=togglebutton}"
VerticalOffset="{Binding ActualHeight, ElementName=togglebutton}">
【讨论】:
我刚刚做了这样的事情,这真的不是那么棘手,但它确实需要自定义放置您的弹出窗口。声明弹出窗口时,只需将 PlacementMode 属性设置为 Custom,然后将 CustomPopupPlacementCallback 属性设置为您要使用的方法。
this.trayPopup.CustomPopupPlacementCallback = GetPopupPlacement;
private static CustomPopupPlacement[] GetPopupPlacement(Size popupSize, Size targetSize, Point offset)
{
var point = SystemParameters.WorkArea.BottomRight;
point.Y = point.Y - popupSize.Height;
return new[] { new CustomPopupPlacement(point, PopupPrimaryAxis.Horizontal) };
}
【讨论】:
这很棘手,没有简单的答案。 关于你的问题,你说:
弹出窗口的实际高度和宽度将根据 正在显示的消息。
您不用担心,这是 WPF Popup 控件的默认行为。
确保你想成为的职位的步骤是:
有关使用 Popup 的自定义放置的更多信息,请参阅:
【讨论】:
我也一直在尝试做类似的事情,并且更喜欢在 XAML 中做事情。我在多显示器上使用Placement=Left 时遇到了问题,因为弹出窗口会跳转到另一个屏幕,并且会在中间消失。使用Position=Relative 并使用绑定到它将与之匹配的容器来调整偏移量更可靠。
<Popup x:Name="RightPopupContainer"
StaysOpen="False"
Placement="Relative"
PlacementTarget="{Binding ElementName=BigContainer}"
Height="{Binding ElementName=BigContainer, Path=ActualHeight}"
AllowsTransparency="True"
PopupAnimation="Fade">
<Popup.HorizontalOffset>
<MultiBinding Converter="{StaticResource SubtractionConverter}">
<MultiBinding.Bindings>
<Binding ElementName="BigContainer" Path="ActualWidth" />
<Binding ElementName="RightPopupContainer" Path="Child.ActualWidth" />
</MultiBinding.Bindings>
</MultiBinding>
</Popup.HorizontalOffset>
</Popup>
SubtractionConverter 是一个简单的多绑定转换器,它从RightPopupContainer.Child.ActualWidth 中减去BigContainer.ActualWidth(弹出窗口始终具有宽度 = 0,子级具有大小)。这使得它可以准确地放置在容器的边缘,并且当容器大小发生变化时它会自动更新。
这里是另一个执行相同结果的选项,而不是多重绑定。
在包含您的 Popup 的 UserControl 或 Window 中,在代码隐藏中为 LayoutUpdated 创建一个事件侦听器。在后面的代码中你可以做如下逻辑:
private void UpdateElementLayouts(object sender, System.EventArgs e)
{
if (RightPopupContainer?.IsOpen == true && RightPopupContainer.Child is UserControl content)
{
RightPopupContainer.HorizontalOffset = BigContainer.ActualWidth - content.ActualWidth;
}
}
【讨论】: