Как создать постраничный ItemsControl или Panel с повторяющимся заголовком? - PullRequest
1 голос
/ 13 мая 2009

Я пытаюсь создать Panel или ItemsControl, которые будут отображать элементы в виде:

Заголовок 1

  • Подпункт 1
  • Подпункт 2
  • Подпункт 3

Заголовок 2

  • Подпункт 1
  • Подпункт 2

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

Я добился определенного прогресса в работе с MeasureOverride и ArrangeOverride, но продолжаю сталкиваться с тупиками. Это действительно расстраивает, потому что это что-то вычислительно тривиальное, но кошмар в WPF / Silverlight. Если вы когда-либо работали с пакетами отчетов, концепция очень похожа на это.

Я продолжаю возвращаться к тому факту, что не могу определить высоту, пока не добавлю дочерние элементы в элемент управления (используя Dispatcher.BeginInvoke).

У кого-нибудь есть предложения по выполнению этого? Заранее спасибо!


Редактировать

[WPF] ObservableCollection и ListBoxItem Проблема генерации DataTemplate

Эта ссылка очень похожа на предложенную mdm20, но я все еще застрял. Каждый раз, когда я пытаюсь получить ActualHeight, он возвращает 0. Кроме того, ItemContainerGenerator в Silverlight 3 возвращает ноль для контейнера, если я не заключаю вызов в операцию Dispatcher.BeginInvoke.

Ответы [ 2 ]

0 голосов
/ 13 мая 2009

Действительно невозможно измерить UIElement напрямую, пока вы не построите его, но вы можете построить элементы списка таким образом, что вы будете заранее знать, сколько места они займут. Например, вы можете использовать Grid для разметки каждого из элементов со строкой известной высоты (скажем, headerHeight) для заголовка и рядами известной высоты для каждого из подпунктов (скажем, subitemHeight) , Затем вы можете рассчитать высоту каждого элемента по форуму headerHeight + numSubitems * subitemHeight. Кроме того, если вы знаете, что количество элементов будет довольно небольшим, скажем, менее 1000, вы можете просто захотеть создать их все заранее, поскольку в этот момент снижение производительности может быть допустимым.

Я согласен, что подобные вещи могут раздражать, но проблема заключается в самой гибкости фреймворка. Эта проблема вычисления высоты делает трудным создание плавного прокручивания, но все еще виртуализации, списка элементов в ListBox или ListView.

0 голосов
/ 13 мая 2009

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

    Size maxSize = new Size(0, 30);
    UIElement templateRoot = template.LoadContent() as UIElement;
    templateRoot.Measure(maxSize);
    Size size = templateRoot.DesiredSize;

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

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

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

Вот как бы я попытался это сделать .. если это вообще имеет смысл :)

...