我最近一直在开发一个RTF编辑器,它只是一个简单的UserControl
,RichTextBox
有一些事件,如PreviewTextInput
和PreviewMouseUp
。< / p>
我注意到有些烦人的东西。
每当调整UI大小并且RichTextBox
有大量文本导致其包装算法触发时,RichTextBox
的性能绝对非常糟糕。
这给应用程序带来了一种非常草率的感觉,好像它的优化程度很差(即使它不是)。
首先我注意到在选择Text时出现这种性能影响,因此我决定使用SelectionChanged
事件而不是PreviewMouseUp
事件,然后获取选择。
然后经过进一步测试后我发现调整大小也造成了巨大的负担。 我说的是负载范围在5%之间 - &gt;配备四核CPU运行频率为3.8GHz的30%!
为了进一步测试,我决定评论我的RichTextBox
并仅包含一个没有定义属性的新RichTextBox
<RichTextBox/>
将其插入窗口,填充文本,然后调整窗口大小以使包装算法再次执行相同操作,使用率高达30%!
我尝试研究这个问题,大多数人最后建议将PageWidth
设置为高值以防止换行:
richTextBox1.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
richTextBox1.Document.PageWidth = 1000;
我不想要,因为我编写的编辑器的前一版本是使用WinForms制作的,可以毫不费力地进行包装,我也希望在新的WPF版本中使用。
有没有其他人遇到过这个问题? 如果是的话,请您指出正确的方向,以消除硬件上的巨大压力?
我有点难过,因为我喜欢WPF,但我确实找到了一个或者另一个与WinForms对应物相比没有优化和/或不实用的对象,RichTextBox
似乎是另一个其中一个案例:(
对于大量的文字感到抱歉,但我真的很想记录这个问题,以防其他一些可怜的灵魂面临这个问题,并且让你们看看我到目前为止所尝试的内容。
答案 0 :(得分:7)
克服这个问题的一种方法可能是切换到&#34;没有换行&#34;调整窗口大小时的模式,但是当用户完成调整大小时 - 切换回正常模式。然后包装算法将在最后执行一次,用户仍然应该对您的应用程序有一个平稳的感觉。示例代码:
public partial class MainWindow : Window
{
public MainWindow() {
InitializeComponent();
this.SizeChanged += OnSizeChanged;
}
private Timer _timer;
private void OnSizeChanged(object sender, SizeChangedEventArgs e) {
// user started resizing - set large page width
textBox.Document.PageWidth = 1000;
// if we already setup timer - stop it and start all over
if (_timer != null) {
_timer.Dispose();
_timer = null;
}
_timer = new Timer(_ => {
// this code will run 100ms after user _stopped_ resizing
Dispatcher.Invoke(() =>
{
// reset page width back to allow wrapping algorithm to execute
textBox.Document.PageWidth = double.NaN;
});
}, null, 100, Timeout.Infinite);
}
}