C# WPF-摆脱RichTextBox中dispatcher的使用

C# WPF-摆脱RichTextBox中dispatcher的使用,c#,wpf,xaml,richtextbox,dispatcher,C#,Wpf,Xaml,Richtextbox,Dispatcher,我有一个从服务器接收消息的WPF应用程序。 我在后台工作程序中侦听消息,如果新消息到达,我将调用新事件 在我的ServerMessage.xaml中,我有一个绑定到ViewModel中的属性的文本框 <TextBox IsReadOnly="True" VerticalScrollBarVisibility="Visible" Text="{Binding ServerMessages}" /> 由于某些情况,我不得不切换到RichTextBox,主要是因为不同的文本颜色和图像。

我有一个从服务器接收消息的WPF应用程序。 我在后台工作程序中侦听消息,如果新消息到达,我将调用新事件

在我的ServerMessage.xaml中,我有一个绑定到ViewModel中的属性的文本框

<TextBox IsReadOnly="True" VerticalScrollBarVisibility="Visible" Text="{Binding ServerMessages}" />
由于某些情况,我不得不切换到RichTextBox,主要是因为不同的文本颜色和图像。 遗憾的是,我无法将任何内容绑定到RichTextBox。我尝试了一些可用的绑定扩展,但都不起作用

为了让它工作,我在事件中使用了RichTextBox.Dispatcher。看起来是这样的:

RichTextBox.Dispatcher.BeginInvoke(
  System.Windows.Threading.DispatcherPriority.Normal,
  new Action(() => 
                  { 
                      TextPointer caretPos = ChatTextBox.CaretPosition.DocumentEnd;
                      new InlineUIContainer(new TextBlock() {  Text = e.ServerMessage }, caretPos);
                      RichTextBox.AppendText("\u2028");
                      RichTextBox.ScrollToEnd();
                  }
            ));
有没有可能摆脱调度器,回到绑定


如果我使用绑定,我会得到一些东西吗?或者调度器也可以吗

对于不同颜色的文本和图像,您可能会使用带有适当ItemTemplate的ItemsControl来代替RichTextBox。然后,您可以将其ItemsSource属性绑定到动态更改的数据项对象集合。FlowDocument和FlowDocumentScrollViewer?我在这里做了一个关于SynchronizationContext的示例:。希望这有帮助。WPF也是如此。我切换到了ItemsControl和SynchronizationContext的组合。问题是,我不能创建一个真正的ItemTemplate,因为每个消息看起来都完全不同,我必须相应地进行调整。因此,我必须进行一次可观察的收集。缺点是我不能在非UI线程中创建它们。这就是我使用SynchronizationContext将生成的Stackpanel添加到ObservableCollection的原因,它绑定到ItemsControl。性能大大提高,从15%的CPU提高到2%的CPU。
RichTextBox.Dispatcher.BeginInvoke(
  System.Windows.Threading.DispatcherPriority.Normal,
  new Action(() => 
                  { 
                      TextPointer caretPos = ChatTextBox.CaretPosition.DocumentEnd;
                      new InlineUIContainer(new TextBlock() {  Text = e.ServerMessage }, caretPos);
                      RichTextBox.AppendText("\u2028");
                      RichTextBox.ScrollToEnd();
                  }
            ));