2010-03-03 5 views
9

Ich baue eine Anwendung, die ein Benutzer zum Einfügen von Text in einer anderen von einem RichTextBox an der aktuellen Cursorposition ermöglichen muss. Ich verbrachte eine viel Zeit mit der FlowDocument ‚s-Objektmodell Schrauben um, bevor er über diese Technik läuft - source und target sind beide FlowDocument s:Wie fügt man Inline-Inhalt von einem FlowDocument in ein anderes ein?

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); 
} 

Das funktioniert erstaunlich gut.

Das einzige Problem damit ich jetzt habe, ist, dass es immer die Quelle als neuer Absatz eingefügt werden. Es unterbricht den aktuellen Lauf (oder was auch immer) am Caret, fügt die Quelle ein und beendet den Absatz. Das ist sinnvoll, wenn die Quelle tatsächlich ist ein Absatz (oder mehr als ein Absatz), aber nicht, wenn es nur (sagen sie) eine Textzeile.

Ich denke, es ist wahrscheinlich, dass die Antwort auf diese wird am Ende zu prüfen, das Ziel zu sehen, ob es nur aus einem einzigen Block besteht, und wenn dies der Fall, setzen Sie die TextRange auf den Anfang und das Ende der Blockieren Sie den Inhalt, bevor Sie ihn im Stream speichern.

Die ganze Welt des FlowDocument ist eine brodelnde Meer von dunklen Geheimnisse zu mir. Ich kann ein Experte darin werden, wenn ich muss (nach Dostojewski: "Der Mensch ist das Tier, das sich an alles gewöhnen kann."), Aber wenn jemand das schon herausgefunden hat und mir sagen kann, wie er das machen soll, würde es mein machen Leben viel einfacher.

Antwort

12

Ihr sofortiges Problem ist, dass Sie TextFormat.Xaml anstelle von TextFormat.XamlPackage verwenden.

Die Eigenschaft, die auch nicht kontrolliert Linien zusammengeführt werden, wenn Dokumente kombiniert werden, ist die Section.HasTrailingParagraphBreakOnPaste Eigenschaft. Diese Eigenschaft ist nur wirksam beim Laden oder Speichern des XamlPackage Textformats. Wenn Sie stattdessen das Textformat Xaml verwenden, wird die Eigenschaft während Save() ausgelassen und während Load() ignoriert.

So ist die einfache Lösung ist, einfach die Last zu ändern und speichern Anrufe:

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

Beachten Sie, dass dies auch ein anderes Problem behebt würden Sie schließlich den Weg laufen: Eingebettete Bitmaps nicht richtig kopiert werden, wenn DataFormats.Xaml verwenden, da es ist nirgends die Bildbits zu setzen. Mit DataFormats.XamlPackage wird ein ganzes Paket erstellt, so dass Bitmaps und andere Paket-Elemente in Ordnung kommen.

Sobald Sie diese Änderung vornehmen, können Sie eine weitere Tatsache feststellen, die für Sie möglicherweise ein Problem darstellt: Ihr Beispielcode verwendet document.ContentStart und document.ContentEnd. Wenn dies Ihr eigentliche Code ist werden Sie feststellen, dass jeder Bereich von document.ContentStart bis document.ContentEnd unbedingt Voll Absätzen besteht, so kopiert es wird immer einen Absatzumbruch am Ende des Einführungs einzufügen. Wenn dies ein Problem ist, verwenden Sie so etwas wie RichTextBox.Selection (wenn diese UI ist angetrieben) oder TextPointer verwenden ContentEnd, bevor die implizite Absatzmarke zu sichern, zum Beispiel:

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

Es wird eine Weile dauern, bis ich kann eigentlich geh und überprüfe das auf Richtigkeit, aber es scheint, als wärst du genau dort gewesen, wo ich gerade bin, und ich schätze die Informationen. –

Verwandte Themen