2016-10-31 3 views
1

Я очень новичок в WPF, и мне нужно посоветовать, как создать представление со многими UIElements в одно и то же время. То, что я хочу сделать, - это просмотр какой-то таблицы с фиксированной шириной и высотой для каждой ячейки. В каждой ячейке может быть случайное число текстовых блоков с другой спиной и forecolor (см. Изображение).Улучшение производительности в WPF со многими UIElements

Image for table-like view with many UiElements

Это то, что я сделал до сих пор ... Я создал UserControl для содержания одной клетки, которая связывает элементы в качестве itemcontrol.

<ItemsControl ItemsSource="{Binding}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <UniformGrid Columns="1" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Border Background="{Binding Backcolor, Converter={StaticResource IntegerToBrushConverter}}" > 
       <Viewbox MaxHeight="20" > 
        <TextBlock TextWrapping="Wrap" Text="{Binding Caption}" 
         Foreground="{Binding Forecolor, Converter={StaticResource IntegerToBrushConverter}}"/> 
       </Viewbox> 
      </Border> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Этот пользовательский контроль также привязан к элементу itemcontrol для представления оси x моей таблицы.

<ItemsControl ItemsSource="{Binding}" > 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Orientation="Vertical" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <local:DayView DataContext="{Binding Days}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

И то же самое делается для оси y с красивым scrollviewer. Итак, проблема в том, что в виртуальном дереве много элементов. В моем примере выборки содержится более 60 000 элементов, перечисленных в дереве. Это приводит к плохой производительности при открытии представления. Прокрутка производительности вполне нормально, но он занимает несколько секунд, чтобы открыть представление.

Я пробовал некоторые вещи, такие как CacheMode и т. Д., Но все это не влияет на производительность открытия. Использование VirtualizationStackPanel приводит к плохой производительности прокрутки. Я даже не могу понять, что так долго нужно для создания Ui. Кажется, что ему нужно много времени, чтобы измерить все UiElemtents, но Im не уверен ...

Есть ли подсказки, чтобы сделать такой вид просмотра UiElement более быстрым? Как я уже сказал, Im очень новый в WPF, и это всего лишь тест производительности. У нас есть такой Ui в Winforms, но там вся таблица была написана пользователем. В WPF так легко перестроить дизайн Winforms с помощью элементов управления контентом, которые я хочу только сделать для себя в качестве последнего средства.

+1

Что вы хотите - это «виртуализация»: вы хотите, чтобы пользовательский интерфейс создавал только те элементы управления, которые в настоящее время прокручиваются. Существует ['VirtualizingStackpanel'] (https://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel% 28v = vs.110% 29.aspx? f = 255 & MSPPError = -2147217396), который делает это. Нет виртуализации UniformGrid. Если вы не можете найти элемент управления, который виртуализирует то, что у вас есть, вы можете посмотреть на создание вертикальной VirtualizingStackPanel, содержащей большое количество горизонтальных VirtualizingStackPanels. Вряд ли идеальный, но это может быть наименьшая проблема. –

+1

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

+0

Я пробовал это с помощью UniformGrid, пытался вытащить конвертер, пробовал фиксированную высоту и ширину и т. Д. - не уверен, что он купил мне что-нибудь вообще. Определенно все еще слишком медленно выпускать. Затем я попытался заменить UniformGrid на VirtualizationStackPanel (и комментировать весь ItemPanel тоже). Он начал * мгновенно *, с той же коллекцией. –

ответ

0

Посмотрите здесь возможное решение вашей проблемы с помощью виртуализации:

WPF Data Virtualization

Кроме того, если вы хотите пойти другим путем, есть коммерческие третьи сторонние библиотеки управления WPF, которые обрабатывают виртуализацию с различными степени успеха. Чтобы назвать несколько: Xceed, Syncfusion, DevExpress и Telerik.

Я даже не могу понять, что так долго нужно для создания Ui.

Надеясь, что вы используете VS2015 (или что-то лучше), есть несколько способов получить ответ на то, что так долго. В Visual Studio есть инструмент визуального дерева (Debug-> Windows), где вы можете увидеть визуальное дерево в реальном времени, и это может помочь вам найти и устранить некоторые элементы пользовательского интерфейса, которые вам действительно не нужны (например, границы внутри более границ, и т. д.)

Во-вторых, вы можете запускать диагностические инструменты (Alt + F2), выбирать использование ЦП и генерировать отчет, в котором вы можете видеть, где ваша программа тратит больше времени. Надеемся, это изолирует проблему до определенных методов, которые впоследствии могут быть оптимизированы.

Кроме того, более подробно о вашей проблеме было бы очень приятно. Что такое код, который заполняет ItemsSource?

+0

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

+0

@Dragos: Спасибо за ваш ответ. Это не похоже на то, что я не пробовал виртуализацию. Но, к сожалению, кажется, что я делаю что-то неправильно или делаю это не в том месте в моем коде интерфейса. Моя первая попытка виртуализации заключалась в том, что она открывается медленно, с 60000 элементами в визуальном дереве, и, когда я прокручивался до последнего элемента, визуальное дерево сокращается до ~ 2000 элементов, которые должны произойти в первую очередь. Я прочитаю статью о виртуализации, спасибо за ссылку. – melwynoo

+0

Итак, если объекты размером ~ 60 тыс. Уменьшены до 2 тыс., Должно быть большое количество сбора мусора, что может значительно замедлить работу приложения. Вы можете использовать коммерческие приложения, такие как dotMemory, чтобы узнать, какие объекты выделяются и собираются. Кроме того, имейте в виду, что WPF имеет один поток рендеринга (и один поток пользовательского интерфейса), см. Здесь полный текст https://msdn.microsoft.com/en-us/library/ms741870(v=vs.110). aspx Также см. это для оптимизации элементов управления в визуальном дереве: https://msdn.microsoft.com/en-us/library/cc716879(v=vs.100).aspx – brakeroo

Смежные вопросы