2010-10-23 63 views
2

我有一個wpf應用程序。有一個奇怪的事情,只要我mousedown ComboBox droparrow成爲所有的UI響應非常緩慢,無論ComboBox是否有項目。 惱人的情況只出現在一些電腦上。 期待回答。爲什麼ComboBox的下拉結果整個應用程序的性能很慢?

+0

我們將需要更多信息。你可以將XAML和代碼放在組合框及其項目集合後面嗎?你還用什麼語言? – Val 2010-10-23 02:17:58

+2

當您在調試會話之外運行時,您是否仍然可以檢查它? – ArielBH 2011-06-01 17:04:01

+0

可能的重複http://stackoverflow.com/questions/8198645/wpf-combobox-performance-problems-by-binding-a-large-collections – MichaelS 2011-12-16 20:31:22

回答

3

我已經看過你可以在網上找到的提示,我只注意到沒有問題。

下面的東西都應該認真遵守,否則虛擬化走了(從MSDN,link拍攝):

  • 產品容器直接添加到ItemsControl的。例如,如果應用程序明確將ListBoxItem對象添加到ListBox,則ListBox不會虛擬化ListBoxItem對象。
  • 將CanContentScroll設置爲false。
  • 將IsVirtualizing設置爲false。
  • 使用項目分組。

下面的樣式對我毫無問題。

<Style x:Key="SimpleComboBox" TargetType="{x:Type ComboBox}"> 
    <Setter Property="ItemsPanel"> 
    <Setter.Value> 
     <ItemsPanelTemplate> 
     <VirtualizingStackPanel IsItemsHost="True" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" KeyboardNavigation.DirectionalNavigation="Contained" /> 
     </ItemsPanelTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

<ComboBox Name="cbTest" IsEditable="True" Style="{StaticResource SimpleComboBox}" /> 


我發揮各地對於具有Kaxaml風格一段時間後,我發現一個小東西。有了這種風格,當我使用IsEditable = "True"時,我遇到了問題,性能下降!

以下樣式對我的作品完美

<Style x:Key="SimpleComboBox" TargetType="{x:Type ComboBox}"> 
    <Setter Property="SnapsToDevicePixels" Value="true"/> 
    <Setter Property="OverridesDefaultStyle" Value="true"/> 
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> 
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> 
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/> 
    <Setter Property="MinWidth" Value="120"/> 
    <Setter Property="MinHeight" Value="20"/> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type ComboBox}"> 
     <Grid> 
      <ToggleButton Name="ToggleButton" Focusable="false" ClickMode="Press" 
         IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"> 
      <ToggleButton.Template> 
       <ControlTemplate TargetType="{x:Type ToggleButton}"> 
       <Grid> 
        <Grid.ColumnDefinitions> 
        <ColumnDefinition /> 
        <ColumnDefinition Width="20" /> 
        </Grid.ColumnDefinitions> 
        <Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2" Background="#C0C0C0" BorderBrush="#404040" BorderThickness="1" /> 
        <Border Grid.Column="0" CornerRadius="2,0,0,2" Margin="1" Background="#FFFFFF" BorderBrush="#404040" BorderThickness="0,0,1,0" /> 
        <Path x:Name="Arrow" Grid.Column="1" Fill="#404040" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/> 
       </Grid> 
       <ControlTemplate.Triggers> 
        <Trigger Property="ToggleButton.IsMouseOver" Value="true"> 
        <Setter TargetName="Border" Property="Background" Value="#808080" /> 
        </Trigger> 
        <Trigger Property="ToggleButton.IsChecked" Value="true"> 
        <Setter TargetName="Border" Property="Background" Value="#E0E0E0" /> 
        </Trigger> 
        <Trigger Property="IsEnabled" Value="False"> 
        <Setter TargetName="Border" Property="Background" Value="#EEEEEE" /> 
        <Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" /> 
        <Setter Property="Foreground" Value="#888888"/> 
        <Setter TargetName="Arrow" Property="Fill" Value="#888888" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </ToggleButton.Template> 
      </ToggleButton> 
      <ContentPresenter Name="ContentSite" IsHitTestVisible="False" 
      Content="{TemplateBinding SelectionBoxItem}" 
      ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
      ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 
      Margin="3,3,23,3" 
      VerticalAlignment="Center" 
      HorizontalAlignment="Left" /> 
      <TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" HorizontalAlignment="Left" VerticalAlignment="Center" 
        Margin="3,3,23,3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}"> 
      <TextBox.Template> 
       <ControlTemplate TargetType="{x:Type TextBox}"> 
       <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" /> 
       </ControlTemplate> 
      </TextBox.Template> 
      </TextBox> 
      <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide"> 
      <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}"> 
       <Border x:Name="DropDownBorder" Background="#FFFFFF" BorderThickness="1" BorderBrush="#888888"/> 
       <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True"> 
       <VirtualizingStackPanel IsItemsHost="True" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" KeyboardNavigation.DirectionalNavigation="Contained" /> 
       </ScrollViewer> 
      </Grid> 
      </Popup> 
     </Grid> 
     <ControlTemplate.Triggers> 
      <Trigger Property="HasItems" Value="false"> 
      <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/> 
      </Trigger> 
      <Trigger Property="IsEnabled" Value="false"> 
      <Setter Property="Foreground" Value="#888888"/> 
      </Trigger> 
      <!-- remove this trigger, because the virtualization is broken!!! 
      <Trigger Property="IsGrouping" Value="true"> 
      <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> 
      </Trigger> 
      -->     
      <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true"> 
      <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/> 
      <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/> 
      </Trigger> 
      <Trigger Property="IsEditable" 
        Value="true"> 
      <Setter Property="IsTabStop" Value="false"/> 
      <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/> 
      <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/> 
      </Trigger> 
     </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
    <Style.Triggers> 
    </Style.Triggers> 
</Style> 

我也已經刪除了扳機。

<Trigger Property="IsGrouping" Value="true"> 
    <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> 
</Trigger> 

希望這有助於

2

既然你提到你還是有同樣的問題時,有一個在ComboBox沒有數據,我懷疑這是一個風格問題。

ComboBox默認的風格,那得到的影響通過鼠標懸停的唯一的事情就是ToggleButton這是你單擊展開CombBox這裏面ButtonChrome控制。

<Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" SnapsToDevicePixels="true"> 

你可以先嚐試刪除代碼

RenderMouseOver="{TemplateBinding IsMouseOver}" 

或用Border完全替換(注意,您將需要刪除IsChecked觸發也一樣)

<Border x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> 

看看如果問題沒有了。

我不是100%確定是什麼導致它,如果你可以發佈你的xaml代碼會有幫助。 :)