分享一个 WPF 气泡弹框

分享一个 WPF 气泡弹框

分享一个 WPF 气泡弹框

独立观察员 2022 年 5 月 28 日

 

一、前言

前段时间,公司项目软件(WPF)中,有个需求是,有些显示文件夹路径的地方,由于路径可能比较长,显示不下,界面只显示出一部分,要求点击时出现气泡弹框来显示完整内容。所要求的 “气泡弹框” 其实就是类似安卓手机上那种吐司(Toast提示框,显示几秒会自动消失的。项目中倒是有一两处已经添加了这种弹框,就是操作成功后会弹出来提示一下,但是那些是直接加在相关的 Xaml 页面中,通过控制其显示和隐藏来实现需求的。而本次涉及比较多页面,所以应该寻找一个比较通用的解决方案。

 

二、参考文章介绍

前面说了,需求就是实现一个类似安卓 Toast 的功能,自然而然地就进行相应的百度搜索,果然找到了一篇博文,从标题上看就很符合需求 ——《WPF 中自制类似微信消息提示框 Toast 控件》(https://blog.csdn.net/weixin_44448313/article/details/107469089),以下是原文实现的功能:

分享一个 WPF 气泡弹框插图

 

可以看到功能还是很强大的,以下是原文实现的效果(动图):

分享一个 WPF 气泡弹框插图1

 

三、我的修改点

1、Placement 定位示例

动图:

分享一个 WPF 气泡弹框插图2

 

这个是演示气泡弹框(Popup)定位机制中的一个叫做 Placement 的属性,代表位置;还有她配套的 PlacementTarget 属性,代表定位的目标对象;这里演示了矩形、窗口、空(Null)这三个定位目标,以及 上下左右、中间、相对、绝对 等位置;界面布局如下:

分享一个 WPF 气泡弹框插图3

 

显示和隐藏通过控制 Popup 的 IsOpen 属性来实现,该属性通过样式设置绑定相关的动态资源:

分享一个 WPF 气泡弹框插图4

 

在后台更改动态资源的值:

分享一个 WPF 气泡弹框插图5

 

由于有些位置是重叠的,所以我给每个 Popup 中的内容(TextBlock)加了个鼠标移上会变淡的动画:

分享一个 WPF 气泡弹框插图6

 

2、修正在有些系统环境显示错位的问题

这个主要是加入了一个系统左撇子、右撇子的修正方法,该方法来源于网络,用于解决 Popup 定位异常的问题,也适用于一些有下拉框的控件(因为它们的下拉框也是 Popup),比如日历控件。直接给出方法代码:

/// <summary>
/// 转换系统的左撇子显示模式为右撇子显示模式
/// </summary>
public static void SetAlignment()
{
    //获取系统是以Left-handed(true)还是Right-handed(false)
    var ifLeft = SystemParameters.MenuDropAlignment;

    if (ifLeft)
    {
        Console.WriteLine($"系统为左撇子,转换为右撇子。");

        // change to false
        var t = typeof(SystemParameters);
        var field = t.GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);
        field.SetValue(null, false);

        ifLeft = SystemParameters.MenuDropAlignment;
    }
}

 

在窗口构造函数中调用:

分享一个 WPF 气泡弹框插图7

 

其实现在看这个方法名,应该叫做 设置对齐方式。

 

3、更改弹框风格

由于原文是要仿安卓的 Toast,所以它的风格是那种灰色透明的小框框。而本次的使用对象是一个 Windows 的全屏应用,且风格是那种白色偏多的明快风格,所以气泡弹框也要大一些,同时改为白色风格,最终效果如下(动图):

分享一个 WPF 气泡弹框插图8

 

4、支持设置宽高和边距

动图:

分享一个 WPF 气泡弹框插图9

 

原版是固定的宽度,我改为了支持自动宽度,这样就能根据文字长度自动变宽。

可以注意到上图在演示长文本时,左右两个弹框的高度都比较高,但是左边的文字被截断了,而右边的能自动换行,这是为什么呢?原来左边设置的 ToastWidth,而右边设置的是 TextWidth,如下所示:

分享一个 WPF 气泡弹框插图10

 

至于边距,是通过 ToastMargin 属性来设置的:

分享一个 WPF 气泡弹框插图11

 

5、其它调用方式

(1)输入框点击调用

这个就是通过鼠标点击事件来触发而已(动图):

分享一个 WPF 气泡弹框插图12

 

(2)通过命令调用

这个效果就不演示了,主要就是在绑定基类中添加了一个针对屏幕的弹框命令和一个针对窗体的弹框命令:

分享一个 WPF 气泡弹框插图13

 

针对屏幕的命令需要一个参数,传递弹框内容;针对窗体的命令需要两个参数(通过多值绑定来传递),传递弹框内容和窗体对象:

分享一个 WPF 气泡弹框插图14

 

四、代码资源

本文主要是展示一些效果,以及部分修改的代码。实现机制可以通过查看原版文章讲解以及修改前后的代码来学习了解,具体资源链接如下。

原文链接:https://blog.csdn.net/weixin_44448313/article/details/107469089 

原文原始代码:https://gitee.com/DLGCY_Clone/WpfToast/tree/master/ 

包含修改点的原文风格代码:https://gitee.com/DLGCY_Clone/WpfToast/tree/Gray 

本文对应的代码:https://gitee.com/DLGCY_Clone/WpfToast/tree/Blog20220528 

最新代码(新风格):https://gitee.com/DLGCY_Clone/WpfToast/tree/dlgcy 

效果:

分享一个 WPF 气泡弹框插图15

 

全文完,谢谢阅读!

 

原创文章,转载请注明: 转载自 独立观察员

本文链接地址: 分享一个 WPF 气泡弹框[http://dlgcy.com/share-a-wpf-bubble-popup-like-toast/]

Leave a Reply