我们正在开发.Net 4.0 C#WPF业务线应用程序,需要向用户显示(只读)大型文本文件。 SO中所述的TextBlock
不是一个选项,并尝试了建议的AvalonEdit控件。运行AvalonEdit.Sample独立应用程序可以在不到一秒的时间内加载一个4k行的4MB文件,但是当将AvalonEdit TextEditor
嵌入我们的WPF应用程序时花费20秒,几乎与之前的TextBlock
相同
UI非常复杂,具有树形菜单和表单的分割器。该表单有几个拆分器来创建可调整大小的区域,其中一个包含一个选项卡控件。其中一个标签项包含来自AvalonEdit的TextEditor
。
XAML
<avalonEdit:TextEditor Name="Tbx" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" />
CS
public void ShowFile(string path)
{
Tbx.Text = string.Empty;
ThreadPool.QueueUserWorkItem(o => {
var lines = File.ReadAllLines(path).Join("\n");
Dispatcher.BeginInvoke(() => Tbx.Text = lineas);
});
}
加载文件时,我的笔记本电脑i7 4核CPU使用率为33%。
有关AvalonEdit TextEditor
作为独立应用和自定义WPF应用中的不同行为的任何建议吗?
如何使用TextEditor
加载大文件(10MB,10k行)?
更新
视觉树:
TextEditor
的属性:
我删除了一个托管TextEditor
的ScrollViewer,但是效果不佳。
更新2:
我将TextEditor
移动到一个新窗口以减少布局,但仍然表现不佳。
新的简化视觉树:
Grid
列和行定义为*
。
TextEditor
的属性:
答案 0 :(得分:3)
我发现虚拟化不是水平执行的。在我的情况下,我有一个大的XML文件,没有换行,所以大量的水平滚动,并花了10秒+来渲染。一旦格式化相同的文本(使用换行符),它就会呈现亚秒级。
答案 1 :(得分:2)
查看应用程序的可视树(Snoop可能会有帮助)并查看TextEditor控件周围是否有任何ScrollViewer。
滚动查看器为所包含的控件提供了无限空间,这将禁用任何UI虚拟化并破坏性能(编辑器需要渲染整个文档,而不仅仅是可见部分)。
如果您出于某种原因需要嵌套滚动查看器,请查看Nested Scroll Areas问题上的答案,了解如何避免为所包含的控件提供无限空间。
答案 2 :(得分:0)
TextDocument类有一个名为SetOwnerThread()的函数,从doc开始,你似乎可以临时设置不同的线程来加载和渲染doc。
以下是来自TextDocument.cs的评论
/// <summary>
/// Transfers ownership of the document to another thread. This method can be used to load
/// a file into a TextDocument on a background thread and then transfer ownership to the UI thread
/// for displaying the document.
/// </summary>
/// <remarks>
/// The owner can be set to null, which means that no thread can access the document. But, if the document
/// has no owner thread, any thread may take ownership by calling SetOwnerThread.
/// </remarks>