title: Slow ComboBox Performance
body: <p>As explained in the following article <a href="http://vbcity.com/blogs/xtab/archive/2009/12/15/wpf-using-a-virtualizingstackpanel-to-improve-combobox-performance.aspx" rel="nofollow">http://vbcity.com/blogs/xtab/archive/2009/12/15/wpf-using-a-virtualizingstackpanel-to-improve-combobox-performance.aspx</a>, I use the <strong>VirtualizingStackPanel</strong> to <strong>improve</strong> the <strong>performance</strong> of my project's <strong>ComboBoxes</strong>.</p>
  
  <p>And it works great ... until I apply a style to ComboBox to change the layout (I found the style here : <a href="http://msdn.microsoft.com/en-us/library/ee230084.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ee230084.aspx</a>)</p>
  
  <p>Here is the source code of a sample which demonstrate the matter (figuring that ItemSource propery of the ComboBox are filled with 10 000 items).</p>
  
  <p>If anyone has an idea ...</p>
  
  <pre><code>    &lt;Window.Resources&gt;
  
      &lt;!-- Fill Brushes --&gt;
      &lt;LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#FFF" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#CCC" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;LinearGradientBrush x:Key="HorizontalNormalBrush" StartPoint="0,0" EndPoint="1,0"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#FFF" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#CCC" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#FFF" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#EEE" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;LinearGradientBrush x:Key="HorizontalLightBrush" StartPoint="0,0" EndPoint="1,0"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#FFF" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#EEE" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;LinearGradientBrush x:Key="DarkBrush" StartPoint="0,0" EndPoint="0,1"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#FFF" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#AAA" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;LinearGradientBrush x:Key="PressedBrush" StartPoint="0,0" EndPoint="0,1"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#BBB" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#EEE" Offset="0.1"/&gt;
                  &lt;GradientStop Color="#EEE" Offset="0.9"/&gt;
                  &lt;GradientStop Color="#FFF" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;SolidColorBrush x:Key="DisabledForegroundBrush" Color="Black" /&gt;
      &lt;SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#E5E5E5" /&gt;
      &lt;SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" /&gt;
      &lt;SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" /&gt;
  
      &lt;!-- Border Brushes --&gt;
      &lt;LinearGradientBrush x:Key="NormalBorderBrush" StartPoint="0,0" EndPoint="0,1"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#AAA" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#AAA" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;LinearGradientBrush x:Key="HorizontalNormalBorderBrush" StartPoint="0,0" EndPoint="1,0"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#AAA" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#AAA" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;LinearGradientBrush x:Key="DefaultedBorderBrush" StartPoint="0,0" EndPoint="0,1"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#AAA" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#AAA" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;LinearGradientBrush x:Key="PressedBorderBrush" StartPoint="0,0" EndPoint="0,1"&gt;
          &lt;GradientBrush.GradientStops&gt;
              &lt;GradientStopCollection&gt;
                  &lt;GradientStop Color="#AAA" Offset="0.0"/&gt;
                  &lt;GradientStop Color="#AAA" Offset="1.0"/&gt;
              &lt;/GradientStopCollection&gt;
          &lt;/GradientBrush.GradientStops&gt;
      &lt;/LinearGradientBrush&gt;
  
      &lt;SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" /&gt;
      &lt;SolidColorBrush x:Key="SolidBorderBrush" Color="#888" /&gt;
      &lt;SolidColorBrush x:Key="LightBorderBrush" Color="#AAA" /&gt;
  
      &lt;!-- Miscellaneous Brushes --&gt;
      &lt;SolidColorBrush x:Key="GlyphBrush" Color="#444" /&gt;
      &lt;SolidColorBrush x:Key="LightColorBrush" Color="#DDD" /&gt;
  
      &lt;ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton"&gt;
          &lt;Grid&gt;
              &lt;Grid.ColumnDefinitions&gt;
                  &lt;ColumnDefinition /&gt;
                  &lt;ColumnDefinition Width="16" /&gt;
              &lt;/Grid.ColumnDefinitions&gt;
              &lt;Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2" Background="{StaticResource NormalBrush}" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="1" /&gt;
              &lt;Border x:Name="Border2" Grid.Column="0" CornerRadius="2,0,0,2" Margin="1" Background="{StaticResource WindowBackgroundBrush}" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="0,0,1,0" /&gt;
              &lt;Path x:Name="Arrow" Grid.Column="1" Fill="{StaticResource GlyphBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/&gt;
          &lt;/Grid&gt;
          &lt;ControlTemplate.Triggers&gt;
              &lt;Trigger Property="ToggleButton.IsMouseOver" Value="true"&gt;
                  &lt;Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" /&gt;
              &lt;/Trigger&gt;
              &lt;Trigger Property="ToggleButton.IsChecked" Value="true"&gt;
                  &lt;Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" /&gt;
              &lt;/Trigger&gt;
              &lt;Trigger Property="IsEnabled" Value="False"&gt;
                  &lt;Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" /&gt;
                  &lt;Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" /&gt;
                  &lt;Setter TargetName="Border2" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" /&gt;
                  &lt;Setter TargetName="Border2" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" /&gt;
                  &lt;Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/&gt;
                  &lt;Setter TargetName="Arrow" Property="Fill" Value="{StaticResource DisabledForegroundBrush}" /&gt;
              &lt;/Trigger&gt;
          &lt;/ControlTemplate.Triggers&gt;
      &lt;/ControlTemplate&gt;
  
      &lt;ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox"&gt;
          &lt;Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" /&gt;
      &lt;/ControlTemplate&gt;
  
      &lt;Style x:Key="ComboBoxBaseStyle" TargetType="ComboBox"&gt;
          &lt;Setter Property="SnapsToDevicePixels" Value="true"/&gt;
          &lt;Setter Property="OverridesDefaultStyle" Value="true"/&gt;
          &lt;Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/&gt;
          &lt;Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/&gt;
          &lt;Setter Property="ScrollViewer.CanContentScroll" Value="true"/&gt;
          &lt;Setter Property="MinHeight" Value="20"/&gt;
          &lt;Setter Property="Template"&gt;
              &lt;Setter.Value&gt;
                  &lt;ControlTemplate TargetType="ComboBox"&gt;
                      &lt;Grid&gt;
                          &lt;ToggleButton Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="false" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"&gt;
                          &lt;/ToggleButton&gt;
                          &lt;ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" /&gt;
                          &lt;TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}"/&gt;
                          &lt;Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide"&gt;
                              &lt;Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}"&gt;
                                  &lt;Border x:Name="DropDownBorder" Background="{StaticResource WindowBackgroundBrush}" BorderThickness="1" BorderBrush="{StaticResource SolidBorderBrush}"/&gt;
                                  &lt;ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True"&gt;
                                      &lt;StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" /&gt;
                                  &lt;/ScrollViewer&gt;
                              &lt;/Grid&gt;
                          &lt;/Popup&gt;
                      &lt;/Grid&gt;
                      &lt;ControlTemplate.Triggers&gt;
                          &lt;Trigger Property="HasItems" Value="false"&gt;
                              &lt;Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/&gt;
                          &lt;/Trigger&gt;
                          &lt;Trigger Property="IsEnabled" Value="false"&gt;
                              &lt;Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/&gt;
                          &lt;/Trigger&gt;
                          &lt;Trigger Property="IsGrouping" Value="true"&gt;
                              &lt;Setter Property="ScrollViewer.CanContentScroll" Value="false"/&gt;
                          &lt;/Trigger&gt;
                          &lt;Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true"&gt;
                              &lt;Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/&gt;
                              &lt;Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/&gt;
                          &lt;/Trigger&gt;
                          &lt;Trigger Property="IsEditable" Value="true"&gt;
                              &lt;Setter Property="IsTabStop" Value="false"/&gt;
                              &lt;Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/&gt;
                              &lt;Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/&gt;
                          &lt;/Trigger&gt;
                      &lt;/ControlTemplate.Triggers&gt;
                  &lt;/ControlTemplate&gt;
              &lt;/Setter.Value&gt;
          &lt;/Setter&gt;
          &lt;Style.Triggers&gt;
          &lt;/Style.Triggers&gt;
      &lt;/Style&gt;
  
  &lt;/Window.Resources&gt;
  
  &lt;StackPanel&gt;
  
      &lt;ComboBox x:Name="CustomerComboBox_WithoutStyle" SelectedValuePath="Id" DisplayMemberPath="Text" &gt;
          &lt;ComboBox.ItemsPanel&gt;
              &lt;ItemsPanelTemplate&gt;
                  &lt;VirtualizingStackPanel /&gt;
              &lt;/ItemsPanelTemplate&gt;
          &lt;/ComboBox.ItemsPanel&gt;
      &lt;/ComboBox&gt;
  
      &lt;ComboBox x:Name="CustomerComboBox_WithStyle" SelectedValuePath="Id" DisplayMemberPath="Text" Style="{StaticResource ComboBoxBaseStyle}" &gt;
          &lt;ComboBox.ItemsPanel&gt;
              &lt;ItemsPanelTemplate&gt;
                  &lt;VirtualizingStackPanel /&gt;
              &lt;/ItemsPanelTemplate&gt;
          &lt;/ComboBox.ItemsPanel&gt;
      &lt;/ComboBox&gt;
  
  &lt;/StackPanel&gt;
  </code></pre>