Каковы мои варианты макета документа в WPF?

Используя FlowDocument WPF, я столкнулся с рядом ситуаций, когда мне нужно было больше контролировать макет документа, от простых вещей (верхние и нижние колонтитулы страниц) до более сложных (сноски, журнальный стиль) и еще более сложных ( художественные тексты с критическим аппаратом - одно из моих актуальных требований).

Однако, насколько я могу судить, мои единственные варианты:

A. Используйте FlowDocument и потеряйте контроль над макетом.

B. Напишите все с нуля, используя TextFormatter.

Вариант A для меня не вариант, а вариант B требует реализации десятков методов и, что более важно, потери мощности FlowDocument и связанных с ним средств просмотра.

Мой вопрос:

Есть ли какая-либо альтернатива, которая позволит мне использовать возможности FlowDocument, который покрывает 90 % моих потребностей в макете, и писать только код, необходимый для реализации остальных 10 %?

РЕДАКТИРОВАТЬ: для меня крайне важен аспект перекомпоновки FlowDocument. Я понимаю, что прошу как перекомпонуемый контент, так и точный контроль над макетом, что несколько противоречиво. Тем не менее, я знаю, что это можно сделать - я написал простую реализацию с использованием TextFormatter, которая выполняет то, что я хочу, но я бы НАМНОГО лучше использовал FlowDocument с каким-то расширением, чтобы избежать повторной реализации каждой функции.

РЕДАКТИРОВАТЬ 2: Кажется, что мне действительно нужно подключиться к внутреннему пагинатору FlowDocument, чтобы я мог дать ему инструкции по созданию пользовательского класса. Есть ли способ сделать это?


person yclevine    schedule 30.06.2010    source источник


Ответы (3)


Текстовая система в WPF в первую очередь предназначена для игры с текстом для использования в пользовательских интерфейсах, а не для создания сложных документов со сносками, заголовками и т. д. Однако структура была написана таким образом, что если вы хотите добавить пользовательские функции, вы можете это сделать.

Первая проблема: сноски и прочее, что соответствует тексту. WPF предоставляет 2 класса для размещения UIElement в тексте: InlineUIContainer и BlockUIContainer. Я бы подумал о написании собственного пользовательского элемента управления, специально разработанного для поведения сноски или чего-то подобного, и поместить его в один из этих двух классов. Я нашел эту удобную диаграмму взаимосвязей в MSDN, если вам нужна дополнительная информация о том, что принимает что (ссылки внизу страницы)

alt text
(источник: Microsoft .com)

Я не совсем уверен, что вы имеете в виду под «рассказом в журнальном стиле». FlowDocument автоматически размещает классы, производные от Block (все, что выделено синим цветом на приведенной выше диаграмме), в доступное пространство, и вы можете заставить текст «обтекать» объекты, используя встроенные элементы Floater и Figure. Вы также можете использовать Figure и Floater для своих верхних и нижних колонтитулов.

Вот пример кода:

    <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, и если вам нужны дополнительные функциональные возможности/параметры макета, создайте новый класс, наследующий Block или Inline или что-то еще, и напишите там дополнительные вещи, чтобы воспользоваться всей работой, которую .net может сделать для вас. Если вам нужна дополнительная информация, вы можете прочитать больше о текстовых материалах в WPF на MSDN:

Очень длинная статья о том, как использовать FlowDocument

Модель текстового содержимого, используемая в WPF ( откуда я взял картинку)

Наслаждайся :)

person Ed Ayers    schedule 18.07.2010
comment
Спасибо. Проблема в том, что Floater не позволяет управлять размещением, а Figure настаивает на том, чтобы хранить все на одной странице. Мне нужно сочетание этих двух. - person yclevine; 23.07.2010
comment
Под журнальным стилем я подразумеваю истории, которые продолжаются на последующих страницах с другим содержанием между ними. - person yclevine; 23.07.2010
comment
хммм, тогда я не знаю, вы могли бы создать свою собственную плавающую фигуру, производную от Inline, и написать специализированный код самостоятельно... Это означало бы, что вы получите пользовательские функции без необходимости переписывать всю систему отображения текста. - person Ed Ayers; 23.07.2010
comment
Это именно то, что я ищу - как настроить плавающую фигуру. Насколько я могу судить, внутренний пагинатор, который использует FlowDocument, не подключается, поэтому получение от Inline не позволит мне управлять макетом. - person yclevine; 23.07.2010
comment
это довольно раздражает... Последнее, о чем я могу думать, это использование рефлектора .Net (red- gate.com/products/reflector), чтобы увидеть, что происходит на самом деле. Кроме того, я боюсь, что у меня нет идей, как решить вашу проблему! - person Ed Ayers; 25.07.2010
comment
Ссылка на изображение на бесплатном хостинге изображений.net не работает. - person CJBS; 22.08.2017

Ответ на самом деле прост: FixedDocument

Теперь, с FixedDocument, вы потеряете гибкость FlowDocument на экране, но получите поддержку практически всего, а DocumentViewer — отличное средство просмотра фиксированных документов.

Кроме того, вы можете сохранять фиксированные документы в формате XPS и просматривать их вне приложения.

В этом коде показано, как взять FLowDocument и преобразовать его в FixedDocument с верхними, нижними колонтитулами и полями. Я думаю, что не должно быть слишком сложно адаптировать этот код для поддержки сносок.

person Nir    schedule 21.07.2010
comment
Спасибо, но гибкость Flow Document для меня жизненно важна. Мне нужно, чтобы документ можно было перекомпоновать, чтобы пользователь мог настроить размер текста и т. д. - person yclevine; 23.07.2010

Мы используем Apache FOP, реализацию XSL-FO с открытым исходным кодом, для создания документов такого типа. На самом деле он написан на Java, но мы используем IKVM для его запуска на .NET. IKVM — это реализация Java с открытым исходным кодом, работающая на .NET. Это работает очень хорошо. 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

person Jeremy    schedule 23.07.2010
comment
Мне не нужно создавать документы (некоторые из них на самом деле изначально PDF-файлы), а отображать их в перекомпоновываемом виде. - person yclevine; 23.07.2010