我正在开发一个发送命令和数据,接收日志和数据等的终端软件……
端子S / W通过USB接口与Arm Cortex通信.
为了开发,我使用C#和WPF文本框作为终端屏幕.
但是,我遇到了一些问题.
与USB接口相比,更新文本框的速度非常慢.
我怎么解决这个问题?
如果你有解决方案或知道WPF为终端做的用户控制.
请告诉我.
谢谢.
其他信息.
1.string属性,用于绑定到TextBox
public string TestString
{
get { return _testString; }
set
{
_testString = value;
RaisePropertyChangedEvent("TestString");
}
}
2.test用于更新日志的功能
StringBuilder testBulider = new StringBuilder();
testBulider.Capacity = 1000000;
for (int i = 0; i < 1000; ++i)
{
testBulider.Append(i.ToString("x4") + "\n");
testString = testBulider.ToString(); // Very Slow Point
}
最佳答案 StringBuilder可能不是这里的方法,通常在循环或其他进程中附加大量数据时使用,并希望在最后调用ToString.在这种情况下,性能比通过内存分配开销做一堆显式字符串连接更好.
我不完全确定你的应用程序,但我猜你只想显示终端的一些输出.我建议你将文本行存储在ObservableCollection属性中,并在收到新行时添加到它.我做了类似的事情,并有一个扩展的RichTextBox与DataSource属性,我用来显示行.我确信有更快的方法可以做到这一点(RichTextBox因其性能而闻名,我每次添加一行时都会构建一个新的内联块),但我从未注意到任何性能问题 – 并且它允许我可以根据事件类型等格式化颜色编码.
无论如何,我已尽力复制我所拥有的内容,同时删除了我的具体实现细节,我没有特别测试.
EventLogBox类:
public class EventLogBox : RichTextBox
{
public EventLogBox()
{
}
static EventLogBox()
{
RichTextBox.IsReadOnlyProperty.OverrideMetadata(
typeof(EventLogBox),
new FrameworkPropertyMetadata(true));
RichTextBox.VerticalScrollBarVisibilityProperty.OverrideMetadata(
typeof(EventLogBox),
new FrameworkPropertyMetadata(ScrollBarVisibility.Visible));
RichTextBox.FontFamilyProperty.OverrideMetadata(
typeof(EventLogBox),
new FrameworkPropertyMetadata(new FontFamily("Courier New")));
}
private void AddItem(string pEntry)
{
Paragraph a = new Paragraph();
Run messageRun = new Run(pEntry);
a.Inlines.Add(messageRun);
this.Document.Blocks.Add(a);
this.ScrollToEnd();
}
private void LoadNewItems()
{
this.Document.Blocks.Clear();
foreach (string entry in DataSource)
{
this.AddItem(entry);
}
}
/// <summary>
/// The source of content (EventLogEntrys)
/// </summary>
public IEnumerable<string> DataSource
{
get
{
return (IEnumerable<string>)GetValue(DataSourceProperty);
}
set
{
SetValue(DataSourceProperty, value);
}
}
/// <summary>
/// Using a DependencyProperty as the backing store for <see cref="DataSource"/>.
/// This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty DataSourceProperty =
DependencyProperty.Register
(
"DataSource",
typeof(IEnumerable<string>), typeof(EventLogBox),
new PropertyMetadata
(
new ObservableQueue<string>(),
new PropertyChangedCallback(DataSourcePropertyChanged)
),
new ValidateValueCallback(IsValidDataSourceProperty)
);
/// <summary>
/// We also ned to impliment the INotifyCollectionChanged interface
/// in order for everything to work properly.
/// </summary>
/// <param name="pValue"></param>
/// <returns></returns>
private static bool IsValidDataSourceProperty(object pValue)
{
return pValue is INotifyCollectionChanged;
}
/// <summary>
/// Callback when the DataSourceProperty changes. Setup the new
/// CollectionChanged events, etc.
/// </summary>
/// <param name="pSender"></param>
/// <param name="pArgs"></param>
private static void DataSourcePropertyChanged(DependencyObject pSender,
DependencyPropertyChangedEventArgs pArgs)
{
EventLogBox s = ((EventLogBox)pSender);
((INotifyCollectionChanged)s.DataSource).CollectionChanged -=
new NotifyCollectionChangedEventHandler(
s.DataSource_CollectionChanged);
((INotifyCollectionChanged)s.DataSource).CollectionChanged +=
new NotifyCollectionChangedEventHandler(
s.DataSource_CollectionChanged);
s.LoadNewItems();
}
/// <summary>
///
/// </summary>
/// <param name="pSender"></param>
/// <param name="pArgs"></param>
private void DataSource_CollectionChanged(object pSender,
NotifyCollectionChangedEventArgs pArgs)
{
IList n = pArgs.NewItems;
switch (pArgs.Action)
{
case NotifyCollectionChangedAction.Add:
{
foreach (string cle in pArgs.NewItems)
{
AddItem(cle);
}
break;
}
case NotifyCollectionChangedAction.Remove:
{
for (int i = pArgs.OldStartingIndex;
i < pArgs.OldItems.Count; i++)
{
this.Document.Blocks.Remove(this.Document.Blocks.ElementAt(i));
}
break;
}
case NotifyCollectionChangedAction.Replace:
{
break;
}
}
}
}
ViewModel中的属性
private ObservableCollection<string> mLines = new ObservableCollection<string>();
public ObservableCollection<string> Lines
{
get
{
return mLines;
}
}
在XAML中:
<local:EventLogBox DataSource="{Binding Path=Lines}" Height="100"/>
然后,当您从终端收到新线路时,请致电
Lines.Add(newLine);