c# – RichTextBox用表情符號/圖像替換字符串


在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更容易使用.你可能想要考慮一下.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM