Печать визуалов с помощью пользовательского пагинатора - PullRequest
0 голосов
/ 25 августа 2010

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

Я могу добавить элементы на страницах, но иногда элемент нужно разделить на две части. Кто-нибудь знает хороший алгоритм разделения, чтобы текст внутри этого элемента не разбивался по горизонтали?

Довольно сложно найти решения для этого вида нумерации страниц. Все примеры нумерации страниц, которые я нашел, имеют фиксированную высоту элементов. Использование FlowDocument не вариант, потому что он имеет проблемы с производительностью при использовании многих элементов.

Спасибо за советы.

1 Ответ

0 голосов
/ 25 августа 2010

Я решил эту проблему, создав присоединенное свойство зависимости в статическом классе, PaginationBlocking:

public static class PaginationBlocking
{
    public static IList<UIElement> GetBlockList(UIElement element)
    {
        return (IList<UIElement>)element.GetValue(BlockListProperty);
    }

    public static void SetBlockList(UIElement element, IList<UIElement> value)
    {
        element.SetValue(BlockListProperty, value);
    }

    public static readonly DependencyProperty BlockListProperty =
        DependencyProperty.RegisterAttached("BlockList", typeof(IList<UIElement>), 
            typeof(PaginationBlocking), new UIPropertyMetadata(null, OnBlockListPropertyAttached));

    static void OnBlockListPropertyAttached(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var element = d as UIElement;
        if(element.is_null() || (bool)element.GetValue(IsBlockListOwnerProperty)) return;

        var list = e.NewValue as IList<UIElement>;
        if(list.is_null()) return;

        if(!list.Contains(element)) list.Add(element);
    }
}

Я прикрепляю свойство к любому элементу, который не хочу разбивать на страницы:

<local:MyUserControl Height="20" UI:PaginationBlocking.BlockList="{Binding blockList}" />
<local:MyUserControl Height="30" UI:PaginationBlocking.BlockList="{Binding blockList}" />

Очевидно, вы должны иметь List<UIElement>, к которому вы можете привязаться. Привязка UIElement добавляет ее в связанный список.

Я делаю пагинацию, создав VisualBrush и нарисовав фон Canvas им. Когда я делаю нумерацию страниц, я перечисляю все элементы в списке, чтобы получить их смещение по оси Y относительно верхнего левого угла. Я повторяю, пока не достигну элемента, у которого смещение по оси y превышает доступное пространство для страницы. Я в основном вычитаю один элемент и делаю его последним на странице.

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

...