简单文本显示窗口

时间:2012-09-10 14:27:22

标签: c# wpf

我正在尝试查找/开发一种非常轻量级的方法,以便在桌面应用程序的窗格中显示文本。除了为所有文本设置单一字体外,我没有文本格式的要求。我尝试过使用TextBox,TextBlock和各种可观察的集合。计算效率至关重要。

文本由应用程序创建,永远不会被用户修改。最重要的要求是应用程序通常以每秒100到700行的速度生成文本,峰值速率为每秒1900行。应用程序运行几天并不罕见。理想情况下,显示将连续滚动,以便最后添加的行始终可见。

我当前的实现使用TextBox(对于更长的时间段,我目前别无选择,只能禁用文本显示)。我尝试过的事情包括:

  • 设置IsUndoEnabled =“False”
  • 删除n之后添加的每行文本的第一行文本(通常为1000)。这真的很难看,促使我尝试将其重新设计为MVVM。
  • 使用Observable Collection或BindingList与ListView(ala MVVM)(令人惊讶的是,这比TextBox更糟糕,即使有以下内容)
  • 禁止更改集合/列表,以便延迟UI更新 “闲置”期间。

我可以提供有关我尝试过的更多细节,但我不想从写一本书开始。

这是我目前的XAML实施:

<TextBox Grid.Row="1" Name="tbTraceLog" IsReadOnly="True" IsUndoEnabled="False" VerticalScrollBarVisibility="Auto" FontFamily="Courier New"/>

在代码隐藏中:

    for (icount = 0; icount < tlData.stringcount; icount++)
    {
        tbTraceLog.AppendText(tlData.s[icount]);          // TextBox implementation
        if (tbTraceLog.LineCount > 1000)
        {
            // Remove one line
            tbTraceLog.Text = tbTraceLog.Text.Substring(tbTraceLog.Text.IndexOf('\n')+1);
        }
    }
    tbTraceLog.ScrollToEnd();

我可以开始使用更基本的文本渲染类吗? TextBlock / TextBox继承了哪些类?

1 个答案:

答案 0 :(得分:0)

我不相信控件选择是问题,我相信你的问题是与维护字符串连接相关的性能。我假设,因为您尝试删除第一个条目以在1000之后添加新条目,因此您不需要保留历史记录。也不需要处理每1秒产生的最大1900条消息。

我会将TextBox作为您的控件。使它成为多行和只读。

为结果创建一个类级别列表:

List<string> list = new List<string>();

创建公共字符串属性:

public string Result 
{ 
    get 
    { 
        return string.Concat(list); 
    } 
}

在您的XAML中,将TextBox.Text绑定到Result属性:

<TextBox Text="{Binding Path=Result}" />

接下来创建一个名为update的类级别布尔值:

private bool update = false;

当您收到要连接的结果时,请检查list.Count&gt; 1000.如果是,则列出.RemoveAt(0)然后list.Add(newTextToAdd + Environment.NewLine)。然后将update设置为true。请注意我假设您收到一次添加一个文本。如果您收到了一组文本,则可以计算要删除的文本数量,然后调用list.AddRange(collection)。

if (list.Count > 1000)
{
    list.RemoveAt(0);
    list.Add(newTextToAdd + Environment.NewLine);
}    
update = true;

创建一个计时器。我会说它设置为1秒钟。然后,当它触发检查我们是否更新了我们的列表。如果是,则提高Result属性更改通知,然后将update设置为false:

if (update)
{
    OnPropertyChanged("Result");
    update = false;
}

应该这样做。我认为string.Concat应该足够快,以便在1秒计时器上有你的负载。我认为使用计时器是可以接受的,因为应用程序每秒生成X条消息。排队到列表也应该没问题,因为如果文本在一秒钟内生成超过1000个,那么它只会错过查看文本。由于您已经尝试将最大值限制为1000,因此似乎不需要支持更多。