WPF HtmlTextBlock 实现对话框高亮与跳转

前言

动手写一个简单的消息对话框一文介绍了如何实现满足常见应用场景的消息对话框。

但是内容区域的文字仅仅起到信息展示作用,对于需要部分关键字高亮,或者部分内容有交互性的场景(例如下图提示信息中的"what's the risk?"需要跳转)则无能为力了。

本文将介绍如何在WPF中灵活的实现消息对话框中局部文字内容高亮或者支持跳转。

HtmlTextBlock的使用

在WPF中,可以采用<Run>或者TextEffect实现文字中部分关键字高亮,但无法同时满足部分内容支持链接跳转功能 。如果能直接使用HTML,问题就迎刃而解了,但是在消息对话框的内容区域放一个webbrowser或cef浏览器有点太臃肿了。

WPF HTML Supported TextBlock分享了一个支持有限HTML标签的WPF控件。

该控件可以支持<b>,<u>,<i>,<a>,<br>,<font>标签,派生自TextBlock控件,并新增了一个依赖属性HtmlProperty接收需要展现的html内容,使用时需要把html内容字符串中的<>[]代替。

xml 复制代码
Content="[font color=red]红色[/font]文字高亮";
<toolkit:HtmlTextBlock Margin="0,0,0,0" FontSize="18"
        HorizontalAlignment="Center" VerticalAlignment="Center" 
        Html="{Binding Content}" />

需要注意的是,用Html绑定的内容中如果包含成对的英文方括号[]都会被当做标签处理,无论是否是上述支持的六种标签,都不会显示出来。

中文方括号【】或者单个的英文方括号则会作为内容直接显示出来。如果用Text绑定内容则全部当成内容显示出来。

修改消息对话框

动手写一个简单的消息对话框中内容区域是使用可选中文本的控件SelectableTextBlock显示内容,只需全部替换为HtmlTextBlock,并用依赖属性HtmlProperty绑定内容即可。

调用的时候只需把内容改为带标签的内容即可。例如:

cs 复制代码
ShowAlertDialog(AlertDialogMode.Normal, AlertDialogType.Info, 
  "打开[a href=https://www.chinadaily.com.cn/]中国日报[/a]网站", 
  yesbuttonText: "确定",
  nobuttonText: "取消", parent: this);

但在使用<a>标签实现链接跳转时并没有用浏览器打开指定页面,调试过程中发现以下关键代码,可以看到HtmlTextBlock是把<a>转换为Hyperlink控件,并把href中的url赋值给NavigateUri达到跳转效果。

cs 复制代码
private Inline UpdateElement(HtmlTag aTag)
{
  Inline retVal = null;

  switch (aTag.Name)
  {
    case "text" :
      retVal = new Run(aTag["value"]);
      if (currentState.Bold) retVal = new Bold(retVal);
      if (currentState.Italic) retVal = new Italic(retVal);
      if (currentState.Underline) retVal = new Underline(retVal);
      break;
    case "br" :
      retVal = new LineBreak();
      break;
  }

  if (currentState.HyperLink != null && currentState.HyperLink != "")
  {
    Hyperlink link = new Hyperlink(retVal);
    link.NavigateUri = new Uri(currentState.HyperLink);
    retVal = link;
  }
   return retVal;
}

然而,只有 Hyperlink的直接或间接父级为导航宿主时,Hyperlink才能导航到NavigateUri属性的值,导航宿主包括System.Windows.Navigation.NavigationWindowSystem.Windows.Controls.Frame或任何可承载 XBAP 的浏览器(包括 Internet Explorer 7、Microsoft Internet Explorer 6 和 Firefox2.0 以上版本)。

因此,需要对这段代码稍作修改。

cs 复制代码
if (currentState.HyperLink != null && currentState.HyperLink.Length > 0)
{
 Hyperlink link = new Hyperlink(retVal);
 try
 {
  link.Click += new RoutedEventHandler((s, e) =>
  {
   Process.Start(new ProcessStartInfo((s as Hyperlink).NavigateUri.AbsoluteUri));
   e.Handled = true;
  });
 }
 catch(Exception ex)
 {
  .....
 }
 retVal = link;
}

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:czwy

出处:cnblogs.com/czwy/p/18273976

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!

相关推荐
小醉你真好12 分钟前
Spring Boot + ShardingSphere 实现分库分表 + 读写分离实战
spring boot·后端·mysql
我爱娃哈哈41 分钟前
微服务拆分粒度,拆得太细还是太粗?一线架构师实战指南!
后端·微服务
泉城老铁1 小时前
EasyPoi实现百万级数据导出的性能优化方案
java·后端·excel
斜月1 小时前
Spring 自动装配原理即IOC创建流程
spring boot·后端·spring
有追求的开发者1 小时前
基于Django和APScheduler的轻量级异步任务调度系统
后端
泉城老铁1 小时前
Spring Boot 整合 EasyPoi 实现复杂多级表头 Excel 导出的完整方案
java·后端·excel
CF14年老兵1 小时前
🔥 2025 年开发者必试的 10 款 AI 工具 🚀
前端·后端·trae
京东云开发者1 小时前
本地缓存 Caffeine 中的时间轮(TimeWheel)是什么?
后端
半部论语2 小时前
Spring **${}** vs **#{}** 语法全景图
java·数据库·spring boot·后端·spring
京东云开发者2 小时前
缓存之美:万文详解 Caffeine 实现原理(上)
后端