2014年8月1日更新:修复如果有多个相同链接解析失败的Bug,谢谢 @Walsh 提供的问题

富文本在移动APP上应用的最多的就是表情了,类似微博,QQ,微信都有对提供对表情和链接的支持,富文本一般包括:文本,表情,超链接

WP上没有提供对富文本的直接编辑,富文本是通过字符串进行转换的,例如:QQ上的表情用斜杠标识(例如:/哈哈),微博上的表情用中括号标识(例如:[兔子])

  本文实现富文本的思路是:

    表情:通过构造正则表达式,匹配相关的表情标识,并替换成相关的表情图片

    链接:通过正则表达式匹配以http://或https://开头的一连串的ASCII字符(空格除外)

在msdn看到RichTextBox支持一个Xaml的属性,可以直接构造Xaml字符串,赋给RichTextBox,但是Xaml属性不支持图片元素,所以如果不需要显示图片的话可以使用该属性

详情见:http://msdn.microsoft.com/zh-cn/library/system.windows.controls.richtextbox.xaml(v=vs.95).aspx

由于需要用到图片元素,所以我们通过构造Xaml然后用XamlReader把Xaml转换为Paragraph,再把Paragraph赋值给RichTextBox.Blocks,从而实现富文本

先看效果图吧

我们对RichTextBox进行扩展,添加一个新属性Text

定义RichTextBox之前,我们先说明表情字典的加载,我把表情字典保存在一个txt文件中,在加载的时候进行读取

表情字典在文件中的定义如下

sina/s001.png,[兔子]
sina/s002.png,[熊猫]
sina/s003.png,[给力]
sina/s004.png,[神马]
sina/s005.png,[浮云]
sina/s006.png,[织]
sina/s007.png,[围观]

然后在需要的时候从文件中读取(放在RichTextBoxExt)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup; namespace RichTextDemo
{
public class RichTextBoxExt : RichTextBox
{
#region 富文本Text public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(RichTextBoxExt), new PropertyMetadata(default(string), TextChangedCallback)); private static void TextChangedCallback(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var richTextBox = (RichTextBoxExt)dependencyObject; var text = (string)dependencyPropertyChangedEventArgs.NewValue;
var p = richTextBox.ConvertToElement(text);
richTextBox.Blocks.Clear();
richTextBox.Blocks.Add(p);
} public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
} #endregion //1、由于RichTextBox的Xaml属性不支持图片,所以没办法直接通过RichTextBox的Xaml属性直接处理
// 这里通过构造XAML并使用XamlReader进行读取转换达到富文本的目的
// 富文本包括:文本,图片,链接三种元素
// 我们只需要分别对图片和链接进行处理就可以
/// <summary>
/// 将文字转为富文本(文字+图片表情+链接)
/// </summary>
public Paragraph ConvertToElement(string input)
{
if (input == null)
{
return new Paragraph();
} //匹配普通链接(遇到空格或非Ascii字符则停止)
var mc = Regex.Matches(input, @"http://[\x21-\x7e-[\s]]+|http://[\x21-\x7e-[\s]]+|http://[\x21-\x7e-[\s]]+$"); //记录是否重复
var matchs = new List<string>(); foreach (Match m in mc)
{
if (matchs.Contains(m.Value))
{
//如果有重复匹配项,则跳过
continue;
} //这里链接用蓝色显示,不加下划线(注意,这里使用系统的浏览器IE打开)
input = input.Replace(m.Value.Substring(, m.Value.Length),
string.Format(@"<Hyperlink NavigateUri=""{0}"" MouseOverTextDecorations=""None"" MouseOverForeground=""Blue"" Foreground=""Blue"" TargetName=""_blank"" >{0}</Hyperlink>",
m.Value)); matchs.Add(m.Value);
}
matchs.Clear(); //匹配安全连接
mc = Regex.Matches(input, @"https://[\x21-\x7e-[\s]]+|https://[\x21-\x7e-[\s]]+|https://[\x21-\x7e-[\s]]+$");
foreach (Match m in mc)
{
if (matchs.Contains(m.Value))
{
//如果有重复匹配项,则跳过
continue;
}
input = input.Replace(m.Value.Substring(, m.Value.Length),
string.Format(@"<Hyperlink NavigateUri=""{0}"" MouseOverTextDecorations=""None"" MouseOverForeground=""Blue"" Foreground=""Blue"" TargetName=""_blank"" >{0}</Hyperlink>",
m.Value));
matchs.Add(m.Value);
} //表情字典
var dict = EmotionDictionary; //构造正则模式串(匹配表情)
var builder = new StringBuilder();
foreach (var key in dict.Keys)
{
builder.Append(key.Replace("[", @"\[").Replace("]", @"\]").Replace("{", @"\{").Replace("}", @"\}"));
builder.Append("|");
}
//定义一个Regex对象实例
var r = new Regex(builder.ToString().Substring(, builder.Length - ));
mc = r.Matches(input);
foreach (Match m in mc)
{
//表情替换图片
input = input.Replace(m.Value, string.Format(@"
<InlineUIContainer>
<Border>
<Image Source=""/Assets/Emotions/{0}"" Width=""30"" Height=""30""/>
</Border>
</InlineUIContainer>
", dict[m.Value]));
} var xaml = string.Format(@"<Paragraph
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
<Paragraph.Inlines>
<Run></Run>
{0}
</Paragraph.Inlines>
</Paragraph>", input); return (Paragraph)XamlReader.Load(xaml);
} #region 表情字典 private static Dictionary<string, string> emotionDictionary;
public static Dictionary<string, string> EmotionDictionary
{
get
{
if (emotionDictionary == null)
{
emotionDictionary = new Dictionary<string, string>(); var files = new[] { "sina", "emoji" }; foreach (var file in files)
{
using (var stream = Application.GetResourceStream(
new Uri(string.Format("Assets/Emotions/{0}.txt", file), UriKind.Relative)).Stream)
{
using (var reader = new StreamReader(stream))
{
var line = reader.ReadLine();
while (line != null)
{
var res = line.Split(',');
emotionDictionary.Add(res[], res[]);
line = reader.ReadLine();
}
}
}
}
}
return emotionDictionary;
}
} #endregion
}
}

下面是使用,使用很简单

  <richTextDemo:RichTextBoxExt Text="富文本可以包含表情:{害怕}[心][哈哈],链接:http://www.baidu.com,文字:这是一个富文本控件" Margin="-10,0"/>

RichTextBoxExt会自动把Text的文本中的表情转换为图片,链接转换为超链接,如上面效果图所示

附上Demo

http://files.cnblogs.com/bomo/RichTextDemo.zip

声明:转载请注明出处http://www.cnblogs.com/bomo/

【WP8】富文本功能实现的更多相关文章

  1. [翻译] DTCoreText 从HTML文档中创建富文本

    DTCoreText 从HTML文档中创建富文本 https://github.com/Cocoanetics/DTCoreText 注意哦亲,DTRichTextEditor 这个组件是收费的,不贵 ...

  2. 【WP8.1】富文本

    之前写过一篇WP8下的富文本的文章,但是写的不是很好,整理了一下,分享一下WP8.1下的富文本处理 富文本处理主要是对表情和链接的处理,一般使用RichTextBlock进行呈现 问题说明: 由于Ri ...

  3. 改造百度UMeditor(UEditor-min)富文本编辑器的图片上传功能

    最近项目需要新增一个发布文章的模块,用的是百度的Ueditor富文本编辑器. 公司用的是阿里云的图片服务器,需要直接把文章中图片上传到服务器上,但是这个编辑器的上传图片是直接上传到Tomcat的根目录 ...

  4. 富文本编辑器UEditor自定义工具栏(二、插入图片、音频、视频个性化功能按钮和弹层及自定义分页符)

    导读:本篇将简单探讨插入图片.音频.视频的功能按钮实现方式 传送门:富文本编辑器UEditor自定义工具栏(一.基础配置与字体.背景色.行间距.超链接实现) 一.效果图 1.UEditor自定义工具栏 ...

  5. 富文本编辑器UEditor自定义工具栏(三、自定义工具栏功能按钮图标及工具栏样式简单修改)

    导读 富文本编辑器UEditor提供丰富了定制配置项,如果想设置个性化的工具栏按钮图标有无办法呢?答案是肯定的!前两篇博文简要介绍了通过将原工具栏隐藏,在自定义的外部按钮上,调用UEditor各命令实 ...

  6. springboot中使用kindeditor富文本编辑器实现博客功能

    kindeditor在之前已经用过,现在在springboot项目中使用.并且也在里面使用了图片上传以及回显等功能. 其实主要的功能是图片的处理:kindeditor对输入的内容会作为html标签处理 ...

  7. vue2.0 实现富文本编辑器功能

    前端富文本编译器使用总结: UEditor:百度前端的开源项目,功能强大,基于 jQuery,但已经没有再维护,而且限定了后端代码,修改起来比较费劲 bootstrap-wysiwyg:微型,易用,小 ...

  8. JAVAEE——宜立方商城04:图片服务器FastDFS、富文本编辑器KindEditor、商品添加功能完成

    1. 学习计划 1.图片上传 a) 图片服务器FastDFS b) 图片上传功能实现 2.富文本编辑器的使用KindEditor 3.商品添加功能完成 2. 图片服务器的安装 1.存储空间可扩展. 2 ...

  9. layui 魔改:富文本编辑器添加上传视频功能

    甲方又整新需求了:富文本编辑器需要可以传视频. layui本身的富文本编辑器没有传视频的功能,所以,又到了咱们魔改的时候了. 友情提醒,富文本编辑器 layedit 只有layui的V1版有,V2版没 ...

随机推荐

  1. 问题-MethodAddress返回NIL?MethodAddress与published的关系?

    问题现象:有位朋友(397085381)在Q群里问“为什么书上的可以访问,而自己写的代码访问时为nil” 问题原因:因为要用“Self.MethodAddress('Test')”访问,方法必须放在“ ...

  2. mac下java环境变量配置

    发现一个坑:最近发现有同事按照本文方式配置jdk环境变量一直不成功,后来发现他是使用了“Oh-My-Zsh”,配置文件的路径不是/etc/profile或~/.bash_profile,它有自己的配置 ...

  3. Spring WebSocket初探1 (Spring WebSocket入门教程)<转>

    See more: Spring WebSocket reference整个例子属于WiseMenuFrameWork的一部分,可以将整个项目Clone下来,如果朋友们有需求,我可以整理一个独立的de ...

  4. EF5.x Code First 一对多关联条件查询,Contains,Any,All

    背景 通过多个部门id获取所有用户,部门和用户是多对多. 已知部门id,获取该部门包括该部门下的所有子部门的所有用户. 关系如下: public class Entity:IEntity { publ ...

  5. jQuery(四):HTML代码操作

    html()可以对HTML代码进行操作,类似于元素JavaScript中的innerHTML. 例如: 示例: <!DOCTYPE html> <html lang="en ...

  6. Sublime Text3工具的安装、破解、VIM功能vintage插件教程

    1.安装Sublime Text 3  下载安装:http://www.sublimetext.com/3 Package Control安装:https://sublime.wbond.net/in ...

  7. Java instanceof的进一步理解

    instanceof是Java的一个二元操作符,和==,>,<是同一类东东.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回boo ...

  8. How to deal with "Could not find component on update server. Contact VMware Support or your system administrator." in Vmware.

    手动将vmware安装目录下的vmtools镜像文件,windows.iso文件放到虚拟机的光区里. 再进入虚拟机的系统,在系统里打开光盘进行安装

  9. Google ProtocolBuffers2.4.1应用说明(一)

    1.概念 Protocol buffers是一个用来序列化结构化数据的技术,支持多种语言诸如C++.Java以及Python语言,可以使用该技术来持久化数据或者序列化成网络传输的数据.相比较一些其他的 ...

  10. 【转】【Python】Python 中文编码报错

    用 Python 输出 "Hello, World!",英文没有问题,但是如果你输出中文字符"你好,世界"就有可能会碰到中文编码问题. Python 文件中如果 ...