在RichtTextBox中,我想用表情符号图像自动替换表情符号字符串(例如:D).
我到目前为止工作,除了当我在现有的单词/字符串之间写出表情符号字符串时,图像会在行尾插入.

例如:
你好(在这里插入:D)这是一条消息
结果是:
你好,这是一条消息<<图片 另一个(微小的)问题是插入后的插入位置在插入之前设置. 这就是我已经得到的:

public class Emoticon
{
public Emoticon(string key, Bitmap bitmap)
{
Key = key;
Bitmap = bitmap;
BitmapImage = bitmap.ToBitmapImage();
} public string Key { get; }
public Bitmap Bitmap { get; }
public BitmapImage BitmapImage { get; }
} public class EmoticonRichTextBox : RichTextBox
{
private readonly List<Emoticon> _emoticons; public EmoticonRichTextBox()
{
_emoticons = new List<Emoticon>
{
new Emoticon(":D", Properties.Resources.grinning_face)
};
} protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
Dispatcher.InvokeAsync(Look);
} private void Look()
{
const string keyword = ":D"; var text = new TextRange(Document.ContentStart, Document.ContentEnd);
var current = text.Start.GetInsertionPosition(LogicalDirection.Forward); while (current != null)
{
var textInRun = current.GetTextInRun(LogicalDirection.Forward);
if (!string.IsNullOrWhiteSpace(textInRun))
{
var index = textInRun.IndexOf(keyword, StringComparison.Ordinal);
if (index != -1)
{
var selectionStart = current.GetPositionAtOffset(index, LogicalDirection.Forward);
if (selectionStart == null)
continue; var selectionEnd = selectionStart.GetPositionAtOffset(keyword.Length, LogicalDirection.Forward);
var selection = new TextRange(selectionStart, selectionEnd) { Text = string.Empty }; var emoticon = _emoticons.FirstOrDefault(x => x.Key.Equals(keyword));
if (emoticon == null)
continue; var image = new System.Windows.Controls.Image
{
Source = emoticon.BitmapImage,
Height = 18,
Width = 18,
Margin = new Thickness(0, 3, 0, 0)
}; // inserts at the end of the line
selection.Start?.Paragraph?.Inlines.Add(image); // doesn't work
CaretPosition = CaretPosition.GetPositionAtOffset(1, LogicalDirection.Forward);
}
} current = current.GetNextContextPosition(LogicalDirection.Forward);
}
}
} public static class BitmapExtensions
{
public static BitmapImage ToBitmapImage(this Bitmap bitmap)
{
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Png);
stream.Position = 0; var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.DecodePixelHeight = 18;
image.DecodePixelWidth = 18;
image.StreamSource = stream;
image.EndInit();
image.Freeze(); return image;
}
}
}
 
错误的行是选择.启动?.Paragraph?.Inlines.Add(image);.您将图像追加到段落的末尾.您应该使用InsertBefore或InsertAfter方法之一.

但是要使用这些方法,您应该遍历Inlines并找到要在之前或之后插入的正确内联.这并不困难.您可以通过将selectionStart和selectionEnd与内联的ElementStart和ElementEnd属性进行比较来确定内联.

另一个棘手的可能性是您要插入的位置可能属于内联.然后你应该拆分内联并创建其他三个:

>一个包含插入位置之前的元素
>一个包含图像
>一个包含插入位置后的元素.

然后,您可以删除内联并将新的三个内联插入到正确的位置.

Wpf的RichTextBox没有最漂亮的API.有时可能很难使用.还有一个名为AvalonEdit的控件.它比RichTextBox更容易使用.你可能想要考虑一下.

c# – RichTextBox用表情符号/图像替换字符串的更多相关文章

  1. [No0000A4]DOS命令(cmd)批处理:替换字符串、截取字符串、扩充字符串、获取字符串长度

    1.替换字符串,即将某一字符串中的特定字符或字符串替换为给定的字符串.举例说明其功能:========================================= @echo off set a ...

  2. sql语句格式化数字(前面补0)、替换字符串

    以下是详细分析: 1.select power(10,3)得到1000(即:10的3次方) 2.select cast(1000+33 as varchar) 将1000转换类型(即:将int转化成v ...

  3. js替换字符串问题

    利用正则表达式配合replace替换指定字符. 语法 stringObject.replace(regexp,replacement) 参数 描述 regexp 必需.规定了要替换的模式的 RegEx ...

  4. Notepad++快捷键&正则表达式替换字符串&插件

    Notepad++绝对是windows下进行程序编辑的神器之一,要更快速的使用以媲美VIM,必须灵活掌握它的快捷键,下面对notepad++默认的快捷键做个整理(其中有颜色的为常用招数): 1. 文件 ...

  5. vim查找/替换字符串

    1.:s 命令来替换字符串. :s/vivian/sky/ 替换当前行第一个 vivian 为 sky :s/vivian/sky/g 替换当前行所有 vivian 为 sky :n,$s/vivia ...

  6. 缓存需要注意的问题以及使用.net正则替换字符串的方法

    参考资料:http://www.infoq.com/cn/news/2015/09/cache-problems 正则替换字符串的简单方法: var regTableType = new Regex( ...

  7. 《Python CookBook2》 第一章 文本 - 替换字符串中的子串

    替换字符串中的子串 任务: 给定一个字符串,通过查询一个字符串替换字典,将字符串中被标记的子字符串替换掉. 解决方案: >>> import string >>> ...

  8. js替换字符串的所有示例代码

    js如何替换字符串中所有. /** * 替换字符串中所有 * @param obj 原字符串 * @param str1 替换规则 * @param str2 替换成什么 * @return 替换后的 ...

  9. vim查找/替换字符串 及一些高级用法

    例: 32 ./run 0_39.pkt 0_39.jpg 33 ./run 0_3.pkt 0_3.jpg 34 ./run 0_40.pkt 0_40.jpg 35 ./run 0_41.pkt ...

随机推荐

  1. 「CF1380G」 Circular Dungeon

    CF1380G Circular Dungeon 看懂样例就能做. 虽然我瞪了 20 分钟 菜是原罪 首先可以将从每一个点出发所能获得的价值相加,再除以 \(n\) 就可以得到价值的期望. 所以问题转 ...

  2. Django基础-003 配置Django自带的后台管理,操作数据库

    插入测试数据,可以自己写页面来插入数据 也可以使用Django自带的后台管理,来操作数据表 1.创建用户 python manage.py createsuperuser 2.在浏览器输入地址,进入D ...

  3. stream之map的用法

    一.Stream管道流map的基础用法 最简单的需求:将集合中的每一个字符串,全部转换成大写! List<String> alpha = Arrays.asList("Monke ...

  4. 测试笔记01-Git

    Git工具 Git 一个分布式版本管理工具, 学习资料: https://www.liaoxuefeng.com/wiki/896043488029600/1317161920364578 其中:解决 ...

  5. debug:am trace-ipc源码分析

    debug:am trace-ipc源码分析 目录 debug:am trace-ipc源码分析 一.使用 官网介绍 命令提示 小结 二.源码分析 ActivityManagerShellComman ...

  6. [考试总结]noip模拟9

    因为某些原因,咕掉了一段时间 所以现在才更新 T1 斐波那契 一看就是规律 然而我选择了暴力 其实完全可以打表去找规律. 然后就可以发现父亲的顺序也是斐波那契. 就这 #include<bits ...

  7. odoo14里面的log模块

    日志记录是分析 Odoo 服务器运行服务时发生的操作的最重要工具之一.此外,在大多数情况下,通过分析服务器日志,我们可以清楚地了解错误或存在的任何错误. 最初,如果我们想使用日志记录选项,我们需要从 ...

  8. 算法优化---素数(质数)(Java版)

    4.1优化算法-----输出素数 最简代码请直接移步文末 原代码:https://www.cnblogs.com/Tianhaoblog/p/15077840.html 对应优化如下 优化一:在遍历内 ...

  9. edraw mindmaster pro 8.1.0安装破解教程

    Edraw MindMaster Pro 8.1.0是一款思维导图(脑图)设计软件,头脑风暴.思维整理.项目策划.团队协作,多场景提升您的效率,功能齐全,个人觉得比xmind好用上手,文章手把手教你安 ...

  10. 使用java AWT做一个增加按钮的简单菜单窗体

    package com.ysq.Swing; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Flow ...