2010-03-13 65 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

相關問題