2014-01-16 6 views
2

Я немного привязан (не предназначен для каламбур); У меня есть большая коллекция моделей просмотра (500+), которые отображаются с использованием ItemsControl с WrapPanel как ItemsPanelTemplate. Каждая из этих моделей представлений предоставляет Boolean?, значение которой привязано к свойству IsCheckedCheckBox в пользовательском интерфейсе.CheckBox Binding Slow

Проблема в том, что ... всякий раз, когда я пытаюсь обновить все флажки сразу, это ужасно медленно. Почти 10 секунд, чтобы обновить список из 500 предметов. Если я запускаю код обновления в отдельном потоке, я могу почти следить за обновлением флажков по одному.

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

Я считаю, что виртуализирующий характер WrapPanel может быть виновным. Однако, когда я привязываюсь к свойству IsEnabled вместо IsChecked, я вижу интересный результат; а именно, что изменение значения IsEnabled на значение true медленное, как ожидалось, но переход к ложному происходит мгновенно. Это вызывает у меня подозрение, что анимация флажка виновата, потому что, насколько я могу сказать визуально, при отключении флажка нет анимации, но есть, когда включается. Профилирование показало, что подавляющее большинство времени проводится в методе PropertyChangedEventManager.OnPropertyChanged().

Пример кода ниже, я, к сожалению, вынуждены использовать .NET 3.5:

XAML:

<ItemsControl ItemsSource="{Binding ChildItems}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel Orientation="Horizontal" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.Resources> 
     <DataTemplate DataType="{x:Type SampleViewModel}"> 
      <CheckBox IsThreeState="True" IsChecked="{Binding Path=IncludeInPrinting, Mode=OneWay}" /> 
     </DataTemplate> 
    </ItemsControl.Resources> 
</ItemsControl> 

ViewModel:

public class SampleViewModel : INotifyPropertyChanged 
{ 
    private Boolean? _includeInPrinting; 
    public Boolean? IncludeInPrinting 
    { 
     get 
     { 
      return _includeInPrinting; 
     } 
     set 
     { 
      if (_includeInPrinting != value) 
      { 
       _includeInPrinting = value; 
       RaisePropertyChanged(() => IncludeInPrinting); 
      } 
     } 
    } 
} 

Slow Код:

foreach (SampleViewModel model in ChildItems) 
{ 
    model.IncludeInPrinting = false; 
} 

EDIT: для чего я t Я также вижу всплеск в использовании памяти всякий раз, когда я проверяю все или снимаю галочку с всех флажков. ~ 10MB

EDIT: Анализ производительности, как представляется, подтверждает, что анимация определенно является проблемой. Performance Analysis Hot Path

+0

Что вы можете попытаться отключить Уведомление об имуществе для всех элементов, изменить все свойства, а затем поднять NotifyCollectionChangedAction.Reset в коллекции, содержащей все элементы. – dowhilefor

+0

http://virtualwrappanel.codeplex.com/ – Bas

+0

@dowhilefor Простите мое невежество, но как мне поднять 'NotifyCollectionChangedAction.Reset' на' ObservableCollection'? –

ответ

0

я смотрел бы на следующий контроль, который является открытым исходным кодом на CodePlex ..

http://virtualwrappanel.codeplex.com/ (Примечание: У меня нет affilication с виртуализацией Wrap Panel)

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

+0

Как я уже упоминал выше, я не смог получить этот пользовательский интерфейс контроль за работой. Я получаю то же исключение, упомянутое здесь [WPF - Virtualization WrapPanel] (http://stackoverflow.com/questions/3736989/wpf-virtualising-wrappanel), но принятый ответ не исправил его. –