Как эффективно реализовать фоновую сетку ScrollViewer? - PullRequest
0 голосов
/ 13 апреля 2011

В настоящее время я разрабатываю приложение, которое отображает элементы данных на основе их временной отметки на временной шкале. Следующий скриншот дает вам идею:

Снимок экрана http://www.antiserum.ch/Screenshot.png

Временная шкала содержит строки индекса каждые десять миллисекунд. Он использует Canvas для визуализации элементов данных в правильном положении и StackPanel для отображения строк индекса.

То, что вы видите на скриншоте, именно то, чего я хочу достичь. Однако для отображения строк индекса в настоящее время я заполняю список объектов TimeSpan, увеличенных на 10 мс каждый, чтобы получить полную продолжительность набора данных. Этот список отображается в ItemsControl с шаблоном данных предметов, который рисует белую линию, черный ящик и текст.

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

Итак, мой вопрос: как эффективно нарисовать маркеры индекса?

Я уже рассматривал возможность использования VirtualizingStackPanel для отображения элементов TimeSpan. Это не вариант, потому что ScrollViewer не содержит список индексов напрямую. Кажется, в этом случае виртуализация не работает.

Для пояснения, вот фрагмент моего кода xaml (я удалил шаблонный и стилевой код):

<ScrollViewer x:Name="timelineScroller">
  <Grid>
    <ItemsControl x:Name="IndexMarkers" ItemsSource="{Binding IndexMarkers}" />
    <ItemsControl x:Name="TimelineList" ItemsSource="{Binding Lines}" />
  </Grid>
</ScrollViewer>

Возможным решением может быть создание подкласса ScrollViewer и рисование линий индекса и текста на фоне ScrollViewer при рендеринге. Это должно быть эффективным, поскольку оно может отображать только те линии, которые действительно видимы. Однако я не нашел информации о том, как реализовать такую ​​настройку рендеринга.

Любые идеи приветствуются.

С уважением, Daniel

Ответы [ 2 ]

1 голос
/ 12 мая 2011

Подход, который я наконец выбрал, кажется, работает очень хорошо и без какой-либо виртуализации:

Список маркеров индекса постоянен, но получает RenderTransform-ed в соответствии с текущим временем по модулю ширины маркера. Это заставляет фон ScrollViewer перемещаться с помощью мыши и внезапно возвращается в исходное положение (это происходит только тогда, когда значение «оборачивается» операцией по модулю.

Все, что остается сделать, это обновить метки маркеров именно в этот момент. Этот подход работает настолько хорошо, что скачки меток не воспринимаются пользователем.

0 голосов
/ 13 апреля 2011

Похоже, вам может понадобиться реализовать виртуализацию явно.

Имейте в виду, что вы, возможно, захотите объединить маркеры (как при повторном использовании тех же элементов, где это возможно, потому что создание / уничтожение маркеров может вызвать сбой какого-либо серьезного сборщика мусора при попытке очистить все эти объекты.

Если вы использовали Canvas, вы можете в основном изменить дочерние элементы холста в коде для отображения элементов, которые вам нужны (с указанием их координат).

...