1

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

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

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

  • 设置 IsUndoEnabled="False"
  • 删除在 n 之后添加的每一行文本(通常为 1000)的第一行文本。这真的很难看,并促使我尝试将其重新设计为 MVVM。
  • 使用带有 ListView (ala MVVM) 的 Observable Collection 或 BindingList
  • 抑制收集/列表已更改,以便 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 继承自哪些类?

4

1 回答 1

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 是否 > 1000。如果是,则 list.RemoveAt(0),然后 list.Add(newTextToAdd + Environment.NewLine)。然后将更新设置为真。请注意,我假设您收到的文本是一次添加一个。如果您收到了一组文本,您可以计算要删除的数量,然后调用 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,因此似乎不需要支持更多。

于 2012-09-10T14:57:18.723 回答