2010-03-03 50 views
9

我正在構建一個應用程序,需要允許用戶在另一個插入位置的當前插入位置插入文本RichTextBox。我花了很多時間很多胡鬧與FlowDocument的對象模型跨越這個技術運行前 - sourcetarget都是FlowDocument S:如何將內聯內容從一個FlowDocument插入另一個?

using (MemoryStream ms = new MemoryStream()) 
{ 
    TextRange tr = new TextRange(source.ContentStart, source.ContentEnd);      
    tr.Save(ms, DataFormats.Xaml); 
    ms.Seek(0, SeekOrigin.Begin); 
    tr = new TextRange(target.CaretPosition, target.CaretPosition); 
    tr.Load(ms, DataFormats.Xaml); 
} 

這工作得非常好。

我現在唯一遇到的問題是,它始終將源文件作爲新段落插入。它會打斷插入符的當前運行(或其他),插入源代碼並結束段落。如果源實際上是的一段(或多個段落),但如果它僅僅是(比如說)一行文本則不適用。

我認爲這很可能是最終檢查目標,看它是否完全由一個塊組成,如果是,請將TextRange設置爲指向開頭和結尾處的塊的內容保存到流之前。

FlowDocument的整個世界對我來說都是一片黑暗的奧祕。如果必須的話,我可以成爲這方面的專家(根據陀思妥耶夫斯基:「人是可以適應任何事情的動物)」,但如果有人已經知道了這一點,並可以告訴我如何做到這一點,生活容易得多。

回答

12

您的直接問題是您正在使用TextFormat.Xaml而不是TextFormat.XamlPackage

控制合併文檔時是否合併行的屬性是Section.HasTrailingParagraphBreakOnPaste屬性。此屬性爲僅在加載或保存XamlPackage文本格式時生效。當使用Xaml文本格式時,該屬性在Save()期間被省略,並在Load()期間被忽略。

所以簡單的解決方法是簡單地改變加載和保存電話:

tr.Save(ms, DataFormats.XamlPackage); 
ms.Seek(0, SeekOrigin.Begin); 
tr = new TextRange(target.CaretPosition, target.CaretPosition); 
tr.Load(ms, DataFormats.XamlPackage); 

注意,這也解決了另一個問題,你最終會遇到:使用DataFormats.Xaml當嵌入式位圖就不能正確地複製,因爲那裏無處可放圖像位。隨着DataFormats.XamlPackage整個包建立,所以位圖和其他包裝項目會遇到好的。

一旦你做了這個改變,你可能會發現另一個事實,可能會或可能不是你的問題:你的示例代碼使用document.ContentStartdocument.ContentEnd。如果這是您的實際代碼,您會發現從document.ContentStartdocument.ContentEnd之間的任何範圍都必須包含完整段落,因此複製它總是會在插入結束時插入段落分隔符。如果這是一個問題,使用類似RichTextBox.Selection(如果這是UI驅動的),或者使用TextPointer隱含的段落標記前備份ContentEnd,例如:

var tr = new TextRange(document.ContentStart, 
         document.ContentEnd.GetInsertionPosition(
                LogicalDirection.Backward)); 
+0

這將需要一段時間之前,我其實可以去檢查這是否正確,但它確定好像你已經到了我現在所在的位置,我很欣賞這些信息。 – 2010-03-24 07:29:27

相關問題