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

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

相关推荐
MX_935910 小时前
使用Spring的BeanFactoryPostProcessor扩展点完成自定义注解扫描
java·后端·spring
弹简特10 小时前
【JavaEE05-后端部分】使用idea社区版从零开始创建第一个 SpringBoot 程序
java·spring boot·后端
爬山算法10 小时前
Hibernate(81)如何在数据同步中使用Hibernate?
java·后端·hibernate
我要打打代码10 小时前
关于C#线程 任务
开发语言·数据库·c#
Ivanqhz10 小时前
现代异构高性能计算(HPC)集群节点架构
开发语言·人工智能·后端·算法·架构·云计算·边缘计算
Loo国昌10 小时前
【大模型应用开发】第三阶段:深度解析检索增强生成(RAG)原理
人工智能·后端·深度学习·自然语言处理·transformer
Demon_Hao10 小时前
Spring Boot开启虚拟线程ScopedValue上下文传递
java·spring boot·后端
小高Baby@10 小时前
ShouldBind、ShouldBindJson、ShouldBindQuery的区别
后端·golang
BYSJMG10 小时前
计算机毕设选题推荐:基于Hadoop的交通事故数据可视化分析系统
大数据·vue.js·hadoop·分布式·后端·信息可视化·课程设计
Traced back10 小时前
# C# 基础语法完全指南
开发语言·c#