2010-03-13 41 views
4

我试图实现(作为初始原型),一个可以实时解析的richtextbox控件,以将特定的格式化选项应用到它。这是在WPF中完成的,因此我认为最好的方法是扩展现有的富文本框控件。在WPF中实现解析/可编辑Richtextbox的最佳方法

我遇到了问题,它没有很好地记录下来,并且这些例子很慢(我发现的那些解析每个按键的整个文档)。

我目前决定采用的方式是创建一个可以容纳格式化标签和内容的自定义内联元素。因此,我只需要解析当前段落以及该段落中用于格式化标签的运行。

有没有更好的方法来实现这一目标?请注意,这不适用于基于代码/语法的文档(因此AvalonEdit不合适)。

干杯

回答

4

如果您可以以.NET Framework 3.5及更高版本为目标,需要在每次更改时扫描文档:只需订阅TextChanged事件并使用TextChangedEventArgs.Changes属性获取更改列表。

每当您收到一个TextChanged事件时,迭代Changes集合并从Offset,AddedLength和RemovedLength构造一个TextRange。然后展开适当的TextRange以重新计算格式,然后执行格式化计算并将其更新为独立步骤(在Dispatcher.BeginInvoke回调中),以便最终不会产生递归TextChanged事件。

richTextBox.TextChanged += (obj, e) 
{ 
    var document = richTextBox.Document; 
    var length = document.ContentStart.GetOffsetToPosition(document.ContentEnd); 
    int totalAdd = 0; 
    int totalRemove = 0; 
    foreach(var change in e.Changes) 
    { 
    var expandBy = Math.Max(totalAdd,totalRemove); 

    var startIndex = change.Offset - expandBy; 
    var endIndex = changed.Offset + expandBy + Math.Max(totalAdd, totalRemove); 

    startIndex = Math.Max(startIndex, 0); 
    endIndex = Math.Min(endIndex, length); 

    var startPointer = document.ContentStart.GetPositionAtOffset(startIndex); 
    var endPointer = startPointer.GetPositionAtOffset(endIndex - startIndex); 

    var range = new TextRange(startPointer, endPointer); 
    Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => 
    { 
     DoParsingAndFormatting(ExpandRangeToUnitOfParsing(range)); 
    }); 
    totalAdd += change.AddedLength; 
    totalRemove += change.RemovedLength; 
    } 
}; 

如果你想找到的段落,其中一个变化的开始或结束,您可以使用range.Start.Paragraphrange.End.Paragraph

此外,对于许多情况,将独立于FlowDocument本身的所有文本的副本存储在文档中将会有所帮助。然后,当您对该文档应用更改时,您可以随时更新格式,而无需重新阅读文档。请注意,文本不应该存储在一个大型数组中,而应剪成小块(可能大约1000个字符),并通过按索引组织这些块的树来访问。原因是在巨大数组的开头插入一个字符非常昂贵。

+0

上面的代码仍然适用于最新的WPF RichTextBox?我在问,因为我看到一些必要的变化,使代码正常工作,如startindex,endindex没有正确读取文本更改值,需要重新计算..? – 2013-07-29 22:52:29

+0

JP我想你会发现它只是一个错误的情况。原则是合理的,但找出合适的指标值的实际逻辑并不完全正确。 – donovan 2013-12-16 03:34:04

-3

这里看看这一对CodeProject。这里有一篇关于RichTextBox控件的文章,可能会通过子类化来扩展...看看这个 - 具有更多功能的Extended RichTextBox控件

+3

这是我见过的最差的答案之一。所有这三个链接都浪费了我的时间:所描述的RTF解析器远不如WPF,另外两个链接是过时的WinForms,与问题完全无关。更糟糕的是,在发现甚至不是WPF之前,你必须下载代码! – 2010-03-13 05:59:17

+0

@Ray:对不起,如果我浪费你的时间,有NRTFTree解析器,可以解析RTF,我只是希望你会收集代码给你一个想法... – t0mm13b 2010-03-13 14:53:09

相关问题