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

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

相关推荐
摇滚侠1 小时前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 使用 JdbcTemplate 阅读笔记 32
spring boot·笔记·后端
步行cgn2 小时前
@Configuration 详解:Spring 配置类的核心注解
java·后端·spring
桦说编程4 小时前
【AtomicAgent系列1】变异测试——过去做不起,现在 agent 做得起
后端·ai编程·vibecoding
考虑考虑5 小时前
nginx打印请求日志
运维·后端·nginx
IT_陈寒5 小时前
Python的切片赋值把我坑惨了,这不是bug是特性
前端·人工智能·后端
CoderLiu5 小时前
程序化工具调用(PTC)与动态工作流引擎:深入大模型工具调用的架构演进与实践
前端·人工智能·后端
唐青枫6 小时前
别把日志、权限写进业务方法:C#.NET 动态代理从原理到实战
c#·.net
风云6 小时前
Vane.Dispatch 1.0.0 发布:一个与容器、传输层零耦合的 .NET 服务分发引擎
微服务·mvc·.net·ndf·vane.dispatch
fireworks996 小时前
SpringBoot2接入Knife4j
后端
wei_shuo6 小时前
数据迁移工具实战:KDMS自动化评估与量化决策体系解析
后端