10

我正在构建一个应用程序,该应用程序需要允许用户RichTextBox在另一个插入符号的当前插入位置插入文本。在运行这种技术之前,我花了很多时间来研究FlowDocument's 的对象模型 -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在保存之前将 to 设置在块内容的开头和结尾处到溪流。

整个世界对FlowDocument我来说都是一片黑暗神秘的翻腾海洋。如果必须,我可以成为这方面的专家(根据陀思妥耶夫斯基:“人是可以习惯任何事情的动物。”),但如果有人已经弄清楚了这一点并且可以告诉我如何做到这一点,那会让我生活要容易得多。

4

1 回答 1

14

Your immediate problem is that you are using TextFormat.Xaml instead of TextFormat.XamlPackage.

The property that controls whether or not lines are merged when documents are combined is the Section.HasTrailingParagraphBreakOnPaste property. This property is only effective when loading or saving the XamlPackage text format. When using Xaml text format instead, the property is omitted during Save() and ignored during Load().

So the simple fix is to simply change the Load and Save calls:

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

Note that this also fixes another problem you would eventually run into: Embedded bitmaps will not be copied properly when using DataFormats.Xaml because there is nowhere to put the image bits. With DataFormats.XamlPackage an entire package is built so bitmaps and other package items will come across ok.

Once you make this change you may discover another fact that may or may not be an issue for you: Your sample code uses document.ContentStart and document.ContentEnd. If this is your actual code you will discover that any range from document.ContentStart to document.ContentEnd necessarily consists of full paragraphs, so copying it will always insert a paragraph break at the end of the insertion. If this is a problem, use something like RichTextBox.Selection (if this is UI driven) or use TextPointer to back up ContentEnd to before the implicit paragraph mark, for example:

var tr = new TextRange(document.ContentStart,
                       document.ContentEnd.GetInsertionPosition(
                                                  LogicalDirection.Backward));
于 2010-03-24T04:46:11.677 回答