2010-03-03 19 views
9

Estoy construyendo una aplicación que necesita permitirle a un usuario insertar texto de un RichTextBox en la posición actual del cursor en otro. Me pasé un montón de tiempo de joder con el modelo de objetos FlowDocument 's antes de ejecutar a través de esta técnica - source y target son ambos FlowDocument s:¿Cómo insertar contenido en línea de un FlowDocument en otro?

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

Esto funciona muy bien.

El único problema que tengo ahora es que siempre inserta la fuente como un nuevo párrafo. Rompe la ejecución actual (o lo que sea) en el símbolo de intercalación, inserta la fuente y finaliza el párrafo. Eso es apropiado si la fuente realmente es un párrafo (o más de un párrafo), pero no si es simplemente (por ejemplo) una línea de texto.

Creo que es probable que la respuesta a esto vaya a ser comprobar el objetivo para ver si se trata de un solo bloque, y si lo hace, configurar el TextRange para apuntar al principio y al final del bloquear el contenido antes de guardarlo en la secuencia.

El mundo entero del FlowDocument es un mar de misterios oscuros para mí. Puedo convertirme en un experto si tengo que hacerlo (según Dostoievski: "El hombre es el animal que se puede acostumbrar a todo"), pero si alguien ya lo ha descubierto y puede decirme cómo hacerlo, haría que mi la vida es mucho más fácil.

Respuesta

12

Su problema inmediato es que está utilizando TextFormat.Xaml en lugar de TextFormat.XamlPackage.

La propiedad que controla si o no las líneas se fusionan cuando se combinan los documentos es la propiedad Section.HasTrailingParagraphBreakOnPaste. Esta propiedad es sólo es eficaz al cargar o guardar el formato de texto XamlPackage. Cuando se utiliza formato de texto Xaml, la propiedad se omite durante Save() y se ignora durante Load().

Así que la solución simple es simplemente cambiar el cargar y guardar llama:

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

Tenga en cuenta que esto también soluciona otro problema que con el tiempo se ejecutará en: mapas de bits incrustados no se pueden copiar correctamente cuando se utiliza DataFormats.Xaml porque hay no hay lugar para poner los bits de la imagen. Con DataFormats.XamlPackage se construye un paquete completo para que bitmaps y otros elementos del paquete se vean bien.

Una vez que realice este cambio, puede descubrir otro hecho que puede o no ser un problema para usted: Su código de muestra usa document.ContentStart y document.ContentEnd. Si este es el código real que usted descubre que ninguno gama de document.ContentStart a document.ContentEnd necesariamente consiste en párrafos completos, por lo que la copia siempre va a insertar un salto de párrafo al final de la inserción. Si esto es un problema, usar algo como RichTextBox.Selection (si esto es impulsado por la interfaz de usuario) o utilizar TextPointer para respaldar ContentEnd a antes de la marca de párrafo implícita, por ejemplo:

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

Va a ser un tiempo antes de que realmente puede ir y comprobar esto para la corrección, pero seguro que parece como si hubiera estado exactamente donde estoy ahora, y aprecio la información. –

Cuestiones relacionadas