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

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

相关推荐
customer0820 分钟前
【开源免费】基于SpringBoot+Vue.JS音乐分享平台(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
customer0825 分钟前
【开源免费】基于SpringBoot+Vue.JS渔具租赁系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源
xxxxxmy1 小时前
Django的模板语法
java·javascript·后端·pycharm·django
罗迪尼亚的熔岩1 小时前
C# 中 yield关键字的使用
开发语言·c#
“抚琴”的人2 小时前
C#操作SqlServer数据库事务
数据库·windows·sql·sqlserver·c#
GoppViper2 小时前
golang从http请求中读取xml格式的body,并转成json
xml·后端·http·golang
计算机毕设-小月哥2 小时前
【Python Django + Vue】酒店在线预订系统:用技术说话!
开发语言·vue.js·后端·python·django·计算机毕设·计算机毕业设计
是jin奥2 小时前
Golang 逃逸分析(Escape Analysis)理解与实践篇
开发语言·后端·golang
你是理想2 小时前
springboot创建bean通过构造方法(只有一个构造方法的情况下)注入其他bean(参数)
java·spring boot·后端
yngsqq2 小时前
016集——c# 实现CAD类库 与窗体的交互(CAD—C#二次开发入门)
开发语言·c#