一、 添加BinBindableRichTextBox类
public class BindableRichTextBox : RichTextBox
{
public new FlowDocument Document
{
get { return (FlowDocument)GetValue(DocumentProperty); }
set { SetValue(DocumentProperty, value); }
}
// Using a DependencyProperty as the backing store for Document. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DocumentProperty =
DependencyProperty.Register("Document", typeof(FlowDocument), typeof(BindableRichTextBox), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnDucumentChanged)));
private static void OnDucumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
RichTextBox rtb = (RichTextBox)d;
rtb.Document = (FlowDocument)e.NewValue;
}
}
二、在Xmal中添加控件
<Window
x:Class="PrismIOCtest.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:PrismIOCtest"
xmlns:prism="http://prismlibrary.com/"
xmlns:col="clr-namespace:SocketServer.Helper"
Title="{Binding Title}"
Width="525"
Height="350"
prism:ViewModelLocator.AutoWireViewModel="True">
<Grid>
<col:BindableRichTextBox Document="{Binding ShowSendMessage, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
FontSize="13"
Margin="4,4,4,4"
Grid.Row="0" />
</Grid>
</Window>
三、Viewmodel中添加绑定对象
private FlowDocument _showSendMessage = new FlowDocument(); /// <summary> /// 发送框显示的发送内容 /// </summary> public FlowDocument ShowSendMessage { get { return _showSendMessage; } set { _showSendMessage = value; RaisePropertyChanged("ShowSendMessage"); } }
四、把string转成FlowDocument
/// <summary>
/// 将字符串转换成FlowDocument
/// </summary>
/// <param name="str">原始字符串</param>
/// <param name="fld">要被赋值的Flowdocument</param>
/// <param name="par">要添加到Flowdocument里的Paragraph</param>
private void StrToFlDoc(string str, FlowDocument fld, Paragraph par)
{
//当递归结束以后,也就是长度为0的时候,就跳出
if (str.Length <= 0)
{
fld.Blocks.Add(par);
return;
}
//如果字符串里不存在[时,则直接添加内容
if (!str.Contains('['))
{
par.Inlines.Add(new Run(str));
str = str.Remove(0, str.Length);
StrToFlDoc(str, fld, par);
}
else
{
//设置字符串长度
int strLength = str.Length;
//首先判断第一位是不是[,如果是,则证明是表情,用正则获取表情,然后将字符串长度进行移除,递归
if (str[0].Equals('['))
{
par.Inlines.Add(new InlineUIContainer(new System.Windows.Controls.Image { Width = 20, Height = 20, Source = ContantClass.EmojiCode[GetEmojiNameByRegex(str)] }));
str = str.Remove(0, GetEmojiNameByRegex(str).Length);
StrToFlDoc(str, fld, par);
}
else
{//如果第一位不是[的话,则是字符串,直接添加进去
par.Inlines.Add(new Run(GetTextByRegex(str)));
str = str.Remove(0, GetTextByRegex(str).Length);
StrToFlDoc(str, fld, par);
}
}
}
五、将FlowDocument转成string
/// <summary> /// 获取要发送的Emoji名 /// </summary> /// <param name="str">相对路径的值</param> /// <returns></returns> private string GetEmojiName(string str) { foreach (var item in ContantClass.EmojiCode) { if (item.Value.ToString().Equals(str)) { return item.Key; } } return string.Empty; } /// <summary> /// 将Document里的值都换成String /// </summary> /// <param name="fld"></param> /// <returns></returns> private string GetSendMessage(FlowDocument fld) { if (fld == null) { return string.Empty; } string resutStr = string.Empty; foreach (var root in fld.Blocks) { foreach (var item in ((Paragraph)root).Inlines) { //如果是Emoji则进行转换 if (item is InlineUIContainer) { System.Windows.Controls.Image img = (System.Windows.Controls.Image)((InlineUIContainer)item).Child; resutStr += GetEmojiName(img.Source.ToString()); } //如果是文本,则直接赋值 if (item is Run) { resutStr += ((Run)item).Text; } } } return resutStr; } /// <summary> /// 获取Emoji的名字 /// </summary> /// <param name="str"></param> /// <returns></returns> private string GetEmojiNameByRegex(string str) { string name = Regex.Match(str, "(?<=\\[).*?(?=\\])").Value; return "[" + name + "]"; } /// <summary> /// 获取文本信息 /// </summary> /// <param name="str"></param> /// <returns></returns> private string GetTextByRegex(string str) { string text = Regex.Match(str, "^.*?(?=\\[)").Value; return text; }
public class ContantClass { private static Dictionary<string, BitmapImage> _emojiCode = new Dictionary<string, BitmapImage>();//emoji编码 /// <summary> /// emoji编码 /// </summary> public static Dictionary<string, BitmapImage> EmojiCode { get { return _emojiCode; } set { _emojiCode = value; } } }