首页 > 编程语言 >c# – RichTextBox用表情符号/图像替换字符串

c# – RichTextBox用表情符号/图像替换字符串

时间:2023-06-05 17:00:51浏览次数:37  
标签:表情符号 c# image RichTextBox Forward 内联 var new public

在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#,image,RichTextBox,Forward,内联,var,new,public
From: https://blog.51cto.com/u_4018548/6417983

相关文章

  • Sum of MSLCM 题解
    SumofMSLCM题目大意定义\(\text{MSLCM}(n)\)为所有满足该数集的\(\text{lcm}\)为\(n\)的数集中元素个数最多的数集的所有数字的和,现有多次询问,求\[\sum_{i=2}^n\text{MSLCM}(i)\]思路分析大水题。虽然看着这个东西很可怕,但仔细一想你就会发现,其实\(\text{MSLCM}(n)......
  • ALLEGRO布线完成后进行DRC检查
    DRC:SMDPINtoroutekeepoutspacing间距错误 第二步:将Designmodes中的pintoroutekeepout关闭 ......
  • docker 查看启动容器的运行命令 参数
    1.dockerps-a--no-truncCONTAINERIDIMAGECOMMAND......
  • ChatGPT会取代低代码开发平台吗?
    编程作为一种高端技能,向来是高收入高科技的代名词。近期,伴随着ChatGPT在全球的爆火,过去通过窗口“拖拉拽”的所见即所得方式的低代码开发模式,在更加智能和更低成本的AI搅局之下,又面临了更深层次的影响。低代码平台是一种开发软件应用程序的工具,它可以让用户使用图形用户界面、拖......
  • octave函数
    在octave中有很多的函数应用,例如:命令typemagic查看magic函数的源码1magicistheuser-definedfunctiondefinedfrom:/usr/share/octave/6.4.0/m/special-matrix/magic.m23########################################################################4##......
  • python requests请post接口200,打印提示Unexpected character encountered while parsi
    pythonrequests发起httppost请求,带参数,带请求头,代码设置检查没有问题runpy文件提示Unexpectedcharacterencounteredwhileparsingvalue:p.Path,问题一:body请求形式未进行json格式data=json.dumps(body)dumps的功能是将字典类型转换未json格式的字符串类型。......
  • python 列表 tips stackOverflow数据统计
    PYTHON笔记一Noteone**python中的集合类,有列表,元组,字典和集合四种。定义方式分别为:List=[]Turple=()Dict={key:value}Set={}作为JAVA程序员看来,python中的集合与JAVA中的集合类其实很相似,用着肯定是python更好用,个人认为优点如下:1.没有强定义类型。2.提供了很方便的......
  • JUC是什么?
    JUC表示什么JUC是java.util.concurrent包的缩写,其包结构如下。JUC框架结构JUC是包的简称,JUC可能也是Java核心里最难的一块儿,JUC指的是Java的并发工具包,里边提供了各种各样的控制同步和线程通信的工具类。学习JUC之前,最重要的是了解JUC的结构是什么样的。就如同Java的集合框架的结构......
  • 树之深度优先遍历算法详解(DFS实现) LeetCode94
           本文以如下树结构为例深度优先(DeepFirstSearch)       树的孩子称作子树,对于一个树进行深度优先遍历,即将其某一子树下所有节点遍历完再去遍历其他子树。遍历的顺序以根为参照可分为先序遍历,中序遍历,后序遍历。遍历方式描述先序遍历根左右中序遍历左根右后......
  • 最新Mysql与Navicat下载安装教程
    MySQL安装步骤1、下载MySQL2、安装MySQL3、MySQL的基本使用1、下载MySQL我们先进入MySQL官网,下载MySQL的官方安装包。(网址:http://www.mysql.com)官网首页:点击downloads点击“MySQLCommunity(GPL)Downloads»”点击“MySQLInstallerforWindows”。(我们这里讲的是windows......