Как вставить встроенное содержание от одного FlowDocument в другого?

Я создаю приложение, которое должно позволить пользователю вставлять текст от одного RichTextBox в текущей позиции курсора в другом. Я провел много времени, валяя дурака с FlowDocumentобъектная модель перед натыканием на эту технику - source и target оба FlowDocuments:

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 море загрязнения темных тайн мне. Я могу стать экспертом в нем, если я имею к (на Dostoevsky: "Человек является животным, которое может привыкнуть к чему-либо".), но если кто-то уже понял это и может сказать мне, как сделать это, это сделало бы мою жизнь намного легче.

10
задан Robert Rossney 3 March 2010 в 21:07
поделиться

1 ответ

Ваша непосредственная проблема заключается в том, что вы используете TextFormat.Xaml вместо TextFormat.XamlPackage .

Свойство, управляющее объединением строк при объединении документов, - это свойство Section.HasTrailingParagraphBreakOnPaste . Это свойство действует только при загрузке или сохранении текстового формата XamlPackage . При использовании текстового формата Xaml вместо этого свойство опускается во время Save () и игнорируется во время Load () .

Таким образом, простое решение - просто изменить вызовы Load и Save:

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.ContentStart и document.ContentEnd . Если это ваш реальный код, вы обнаружите, что любой диапазон от document.ContentStart до document.ContentEnd обязательно состоит из полных абзацев, поэтому при его копировании всегда будет вставляться разрыв абзаца в конце. прошивки. Если это проблема, используйте что-нибудь вроде RichTextBox.Выделение (если это управляется пользовательским интерфейсом) или используйте TextPointer для резервного копирования ContentEnd до неявного знака абзаца, например:

var tr = new TextRange(document.ContentStart,
                       document.ContentEnd.GetInsertionPosition(
                                                  LogicalDirection.Backward));
13
ответ дан 3 December 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: