代码之家  ›  专栏  ›  技术社区  ›  Robert Rossney

如何将一个流文档中的内联内容插入到另一个流文档中?

  •  10
  • Robert Rossney  · 技术社区  · 15 年前

    我正在构建一个应用程序,它需要允许用户从 RichTextBox 在另一个插入符号的当前位置。我花了一个 许多 在时间的安排下 FlowDocument 在运行此技术之前的对象模型- source target 都是 流程文档 S:

    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 指向块内容的开头和结尾,然后再将其保存到流中。

    整个世界 流程文档 对我来说是一片黑暗神秘的海洋。如果必须的话,我可以成为这方面的专家(按照陀思妥耶夫斯基的说法:“人是能适应任何事物的动物。”),但如果有人已经知道了这一点,并能告诉我如何做到这一点,我的生活就会轻松得多。

    1 回复  |  直到 15 年前
        1
  •  13
  •   Ray Burns    15 年前

    你现在的问题是 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.ContentStart document.ContentEnd . 如果这是您的实际代码,您将发现 文档.contentstart 文档.contentEnd 必须由完整的段落组成,因此复制时总是在插入的末尾插入段落分隔符。如果这是个问题,可以用 RichTextBox.Selection (如果这是用户界面驱动的)或使用 TextPointer 备份 ContentEnd 到隐式段落标记之前,例如:

    var tr = new TextRange(document.ContentStart,
                           document.ContentEnd.GetInsertionPosition(
                                                      LogicalDirection.Backward));
    
    推荐文章