9

使用 WPF 的 FlowDocument,我遇到了许多需要对文档布局进行更多控制的情况,从简单的东西(页眉和页脚)到更复杂的(脚注、杂志风格的故事流)到更复杂的(带有关键设备的文学文本-我的实际要求之一)。

但是,据我所知,我唯一的选择是:

A. 使用 FlowDocument 并失去对布局的所有控制。

B. 使用 TextFormatter 从头开始​​编写所有内容。

A 对我来说不是一个选项,而 B 需要实现几十种方法,更重要的是,失去了 FlowDocument 及其相关 Viewers 的功能。

我的问题是:

是否有任何替代方案可以让我利用 FlowDocument 的强大功能,它涵盖了我 90% 的布局需求,并且只编写实现其他 10% 所需的代码?

编辑: FlowDocument 的可重排方面对我来说至关重要。我知道我要求可重排的内容和对布局的精确控制,这有些矛盾。但是,我知道这是可以做到的——我使用 TextFormatter 编写了一个简单的实现来完成我想要的,但我更愿意使用带有某种扩展的 FlowDocument 以避免重新实现每个功能。

编辑2:看来我真正追求的是FlowDocument的内部分页器的钩子,这样我就可以给它布置自定义类的说明。有没有办法做到这一点?

4

3 回答 3

6

WPF 中的文本系统主要是为在 UI 中使用文本而设计的,而不是用于生成带有脚注和标题等的复杂文档。但是,该框架已经编写,因此如果您想添加自定义功能,您可以。

第一个问题:脚注和与文本一致的东西。WPF 提供了 2 个类来将UIElements 放入文本中:InlineUIContainerBlockUIContainer. 我会考虑编写自己的自定义控件,该控件专门设计为具有脚注或类似行为的行为,并将其放在这两个类之一中。如果您需要有关接受什么的更多信息,我在 MSDN 上找到了这个方便的关系图表(链接在页面底部)

替代文字
(来源:microsoft.com

我不完全确定您所说的“杂志式故事流”是什么意思。'FlowDocument' 将自动将Block派生类(上图中蓝色的任何内容)排列到可用空间中,您可以使用FloaterFigureinline 元素使文本在对象周围“流动”。您还可以将FigureandFloater用于您的页眉和页脚功能。

这是一些示例代码:

    <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>

您可以将Buttons 替换为您自己的自定义控件(例如,带有脚注的内联按钮)

这段代码是这样的: 设计师视图

我希望这会有所帮助!我不确切知道您要做什么,但我认为您仍然可以使用FlowDocument并仅使用 WPF 提供的大量文本操作设备,如果您确实需要额外的功能/布局选项,请创建一个新类继承BlockInline或其他任何东西,并在那里写下额外的东西,以利用 .net 可以为您做的所有工作。如果您需要更多信息,可以在 MSDN 上阅读有关 WPF 中文本内容的更多信息:

关于如何使用 FlowDocument 的超长文章

WPF 中使用的文本内容模型(我从中获取图像)

玩的开心 :)

于 2010-07-18T18:01:55.930 回答
1

答案其实很简单:FixedDocument

现在,使用 FixedDocument,您将失去 FlowDocument 在屏幕上的灵活性,但您将获得对几乎所有内容的支持,并且 DocumentViewer 是固定文档的出色查看器。

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

此代码显示如何获取 FLowDocument 并将其转换为带有页眉、页脚和边距的 FixedDocument。我认为修改此代码以支持脚注应该不会太难。

于 2010-07-21T09:49:16.127 回答
0

We use Apache FOP, an open source XSL-FO implementation, to create these types of documents. It's actually written in Java but we use IKVM to run it on .NET. IKVM is an open source implementation of Java that runs on .NET. It works pretty nicely. FOP produces PDF, RTF, and several other formats.

The downside is you'll need to learn XSL-FO, but it's not difficult if you're used to old school HTML.

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

http://www.ikvm.net/

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

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

于 2010-07-23T03:05:14.867 回答