FrameworkElement.Arrange проблемы с производительностью - PullRequest
0 голосов
/ 27 мая 2020

У меня драматические c проблемы с производительностью во время реализации функции «масштабирования» для пользовательского интерфейса редактора, который я создаю.

Элементы пользовательского интерфейса в основном структурированы следующим образом:

  • ScrollViewer
    • Canvas («панель редактирования»)
      • ItemsControl
        • Canvas («item»)
          • ScrollViewer
            • Canvas («внутренняя панель редактирования»)
              • ItemsControl
                • Canvas («подпункт»)

Каждый элемент ItemsControls может иметь несколько элементов (позже: меньше 100, но я тестирование только с 1-2). Каждый Canvas, перечисленный выше, на самом деле является UserControl с единственным элементом содержимого Canvas.

Элементы позиционируются путем привязки свойства RenderTransform элементов к экземпляру TranslateTransform и размера путем привязки Width, Height к простым двойным свойствам.

Когда пользователь увеличивает или уменьшает масштаб (путем прослушивания события OnPreviewMouseWheel), вычисляется новое соотношение пикселей и обновляются вышеупомянутые свойства (RenderTransform, Width, Height), в т. правильная реализация INotifyPropertyChanged.

Я пробовал профилировать приложение с помощью инструментов VS2019 Diagnosti c, и большая часть работы, похоже, выполняется методом FrameworkElement.Arrange. И, соответственно, если я использую профилировщик производительности, временная шкала показывает, что «Макетирование» занимает много времени.

При быстром масштабировании и с высоким коэффициентом масштабирования (т. Е. «Панель редактирования» действительно большая) приложение иногда случайным образом зависает на несколько секунд (!), Обрабатывает одно изменение масштабирования, а затем снова останавливается. Похоже на голод в UI-потоке, но я не понимаю почему. * переопределить. Если я включу это, я могу быстрее вызвать зависание, но я считаю, что это общая проблема. Кроме того, удаление элементов с вложенными ScrollViewer s также (очевидно) снижает нагрузку на рендеринг.

Линейка, в частности, кажется дорогостоящей, хотя (согласно Diagnosti c Tools) не из-за необходимые расчеты выполнены в OnRender, а макет - в Arrange.

Этот ответ ({ ссылка }) помог мне изменить способ обновления значений TranslateTransform, но заметно не улучшил производительность.

Эта ссылка интересно, но в конечном итоге не помогло мне решить мою проблему: https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/bb613542 (v = vs.100)? redirectedfrom = MSDN

После прочтения этих двух сообщений я попытался возиться с MeasureOverride и ArrangeOverride, но это привело к другим проблемам, и я чувствовал, что иду не в правильном направлении: WPF MeasureOverride и ArrangeOverride https://www.dotnetforall.com/understanding-measureoverride-and-arrangeoverride/

Я попытался спроектировать компоненты таким образом, чтобы обеспечить быстрый рендеринг, особенно пытаясь сделать макеты элементов управления как можно более независимыми друг от друга, но я, должно быть, делаю что-то не так. Я что-то не замечаю? Могут ли свойства типа ClipToBounds оказать (неожиданное) влияние? ... или Opacity настройки?

Любые идеи были бы очень признательны!

PS Я заметил, что приложение работает намного плавнее (хотя я все еще могу спровоцировать зависание / зависание), если я запускаю его с помощью профилировщика производительности или «Запуск без отладки» - не сильно ли подключение отладчика снижает производительность WPF?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...