在WPF中,我有哪些文档布局选项?

9
使用WPF的FlowDocument,我遇到了许多情况,需要更多地控制文档的布局,从简单的事情(页面标题和页脚)到更复杂的事情(脚注,杂志式故事流),甚至更复杂的事情(具有关键装置的文学文本-我的实际要求之一)。
然而,据我所知,我的选择只有:
A. 使用FlowDocument并失去对布局的所有控制。
B. 使用TextFormatter从头开始编写所有内容。
A对我来说不是一个选项,B需要实现数十种方法,更重要的是,失去了FlowDocument及其相关查看器的功能。
我的问题是: 是否有任何替代方案可以让我利用FlowDocument的强大功能,它涵盖了我90%的布局需求,并仅编写必要的代码来实现其他10%? 编辑:FlowDocument的可重新排版方面对我至关重要。我知道我要求同时实现可重新排版内容和精确的布局控制,这两者有些矛盾。但是,我知道它可以做到-我使用TextFormatter编写了一个基本实现,实现了我想要的效果,但我宁愿使用FlowDocument和某种扩展来避免重新实现每个功能。
编辑2:似乎我真正追求的是对FlowDocument的内部分页器的钩子,以便我可以为其提供有关布置自定义类的指令。是否有任何方法可以做到这一点?
3个回答

6
WPF中的文本系统主要设计用于在UI中玩弄文本,而不是用于生成带有脚注和页眉等复杂文档。但是,如果您想添加自定义功能,则可以使用该框架编写。

第一个问题:与文本内联的脚注和其他内容。 WPF提供了两个类来将UIElement放入文本中:InlineUIContainerBlockUIContainer。我建议编写自己的自定义控件,专门设计成类似脚注或其他类似内容的行为,并将其放入这两个类之一。 如果需要更多关于接受什么的信息,请参考MSDN上的此关系图(链接在页面底部)

alt text
(来源:microsoft.com)

我不完全确定您所说的“杂志式故事流”是什么意思。'FlowDocument'会自动将Block衍生类(上图中蓝色的任何内容)排列在可用空间中,您可以使用FloaterFigure内联元素使文本“流动”围绕对象。您还可以使用FigureFloater来实现标题和页脚功能。

下面是一些示例代码:

    <FlowDocumentScrollViewer>
        <FlowDocument>
            <Paragraph>
                5 green bottles standing on the wall,
                5 green bottles standing on the wall, 
                and if one green bottle was to accidentally fall,
                there would be 4 green bottles standing on the wall;
            </Paragraph>
            <Paragraph>
                4 green bottles standing on the wall,
                4 green bottles standing on the wall, 
                <Floater HorizontalAlignment="Left" Width="250">
                    <BlockUIContainer>
                        <Button>This button is in a Floater</Button>
                    </BlockUIContainer>
                </Floater> 
                and if one green bottle was to accidentally fall,
                there would be 3 green bottles standing on the wall;
            </Paragraph>
            <Paragraph>
                3 green bottles standing on the wall,
                3 green bottles standing on the wall, 
                and if one green bottle was to accidentally fall,
                there would be 2 green bottles standing on the wall;
            </Paragraph>

            <Paragraph>
                2 green bottles standing on the wall,
                2 green bottles standing on the wall,
                and if one green bottle was to accidentally fall,
                <InlineUIContainer>
                    <Button>This Button is inline</Button>
                </InlineUIContainer> 
                there would be 1 green bottle standing on the wall...
            </Paragraph>
        </FlowDocument>
    </FlowDocumentScrollViewer>

你可以用自己的自定义控件替换Button(例如,使用脚注的内联按钮)。
这段代码会生成这样的效果: DesignerView 希望能对你有所帮助!我不知道你具体想做什么,但我认为你仍然可以使用FlowDocument,并且只需使用WPF提供的大量文本处理工具,如果需要额外的功能/布局选项,则创建一个继承BlockInline等的新类,并在其中编写额外的内容,以利用.net可以为你完成的所有工作。 如果您需要更多信息,可以在MSDN上阅读有关WPF中文本内容的更多信息: 如何使用FlowDocument的详细长文 WPF中使用的文本内容模型(我从中获取了图像)

尽情享受吧 :)


谢谢。问题在于Floater不允许控制放置,而Figure坚持将所有内容都放在一页上。我需要两者的结合。 - yclevine
通过杂志风格的流程,我指的是故事会持续到后面的页面,并在其中插入其他内容。 - yclevine
嗯,那我不知道了,你可以创建自己的自定义浮动图形,从Inline派生并编写专门的代码...这意味着你可以获得定制功能,而无需重写整个文本显示系统。 - Ed Ayers
这正是我正在寻找的——如何自定义 floater-figure。据我所知,FlowDocument 使用的内部分页器没有钩子可用,因此从 Inline 派生也不能让我控制布局。 - yclevine
这真的很烦人...我能想到的最后一招就是使用 .Net 反编译器(http://www.red-gate.com/products/reflector)来查看实际发生了什么。除此之外,恐怕我已经没有其他解决你问题的办法了! - Ed Ayers
免费图像托管网站上的图片链接无法使用。 - CJBS

1

答案其实很简单:FixedDocument

现在,使用FixedDocument,您将失去FlowDocument的屏幕灵活性,但您将获得对几乎所有内容的支持,而DocumentViewer是固定文档的一个很好的查看器。

此外,您可以将Fixed文档保存为XPS并在应用程序之外查看它们。

这段代码展示了如何将FLowDocument转换为具有页眉、页脚和边距的FixedDocument。我认为将这段代码调整为支持脚注也不应该太难。


谢谢,但是Flow Document的灵活性对我非常重要。我需要文档具有可重新排版的功能,以便用户可以调整文本大小等。 - yclevine

0

我们使用Apache FOP,一个开源的XSL-FO实现,来创建这些类型的文档。它实际上是用Java编写的,但我们使用IKVM在.NET上运行它。IKVM是一个在.NET上运行的Java开源实现。它的工作非常好。FOP可以生成PDF、RTF和其他几种格式。

缺点是你需要学习XSL-FO,但如果你习惯于老式HTML,那么它并不难。

http://xmlgraphics.apache.org/fop/

http://www.ikvm.net/

http://www.ikvm.net/uses.html

http://www.w3schools.com/xslfo/default.asp


我不需要创建文档(其中一些实际上是PDF),而是以可重排的方式显示它们。 - yclevine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接