如何使 WPF 弹出窗口出现在应用程序的右下角?

Posted

技术标签:

【中文标题】如何使 WPF 弹出窗口出现在应用程序的右下角?【英文标题】:How do I make a WPF popup appear in the lower right corner of an application? 【发布时间】:2011-11-10 23:05:08 【问题描述】:

我正在使用 WPF Popup 控件。我希望它出现在我的应用程序窗口中,固定在窗口的右下角。弹出窗口的实际高度和宽度将根据正在显示的消息而变化。

如果重要的话,弹出的内容是一个Border,包装一个StackPanel,包含多个TextBlock。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

使用 PlacementTarget,Placement=Left,Horizo​​ntal/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">

【讨论】:

请注意,Placement="Left/Right" 并非绝对真理,如果您的用户有触摸屏,他们的 惯用手 设置可以改变这一点。如果我在我的机器上设置了右手,它会反转所有左/右值,左手正确使用放置中的值。似乎 CustomPopupPlacementCallback 是确定的方法。【参考方案2】:

我刚刚做了这样的事情,这真的不是那么棘手,但它确实需要自定义放置您的弹出窗口。声明弹出窗口时,只需将 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) ;

【讨论】:

这会将弹出窗口锚定在显示屏的右下角,不一定是窗口的右下角。【参考方案3】:

这很棘手,没有简单的答案。 关于你的问题,你说:

弹出窗口的实际高度和宽度将根据 正在显示的消息。

您不用担心,这是 WPF Popup 控件的默认行为。

确保你想成为的职位的步骤是:

    将 PlacementTarget 设置为应用程序窗口 将使用相对而不是绝对放置弹出窗口,因为起始位置始终是左上角。但确切的位置也与应用程序的边缘相关,这意味着您必须使用自定义位置。

有关使用 Popup 的自定义放置的更多信息,请参阅:

How to: Specify a Custom Popup Position

【讨论】:

【参考方案4】:

我也一直在尝试做类似的事情,并且更喜欢在 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;
    

【讨论】:

以上是关于如何使 WPF 弹出窗口出现在应用程序的右下角?的主要内容,如果未能解决你的问题,请参考以下文章

如何将组合框弹出窗口与左下 wpf 对齐?

如何使WPF弹出式窗口不被隐藏在主应用程序

如何使用拇指使 WPF 弹出窗口可拖动?

WPF如何实现悬浮窗和主窗口的切换?

请问一下wpf能否实现消息提示框 就像qq消息的那种 右下角弹出 ?能的话 请贴出代码

WPF 右下角弹窗的简单实现