我的ItemsSource组合框中有大约800个项目,当我第一次打开ComboBox时,需要花费很长时间(1-3秒)来显示弹出窗口,就像它生成它一样,但是,如果我禁用了ComboBox的风格几乎立即显示,没有任何减速。我已经尝试了我在网上阅读的所有内容(VirtualizingStack面板无处不在,禁用手写笔支持,触摸支持等等)但我不知道是什么导致了这种减速。下面是我的XAML代码:
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle StrokeDashArray="1 2" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" Margin="2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="templateRoot" SnapsToDevicePixels="true" Background="White" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="#e0e0e0">
<Border x:Name="splitBorder" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" SnapsToDevicePixels="true" Margin="0" HorizontalAlignment="Right" BorderThickness="1" BorderBrush="Transparent">
<Path x:Name="arrow" VerticalAlignment="Center" Margin="0" HorizontalAlignment="Center" Fill="Black" Data="F1 M 0,0 L 2.667,2.66665 L 5.3334,0 L 5.3334,-1.78168 L 2.6667,0.88501 L0,-1.78168 L0,0 Z"/>
</Border></Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="arrow" Value="#3498db">
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#3498db">
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition
MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0" />
</Grid.ColumnDefinitions>
<VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling">
<Popup x:Name="PART_Popup" AllowsTransparency="false" Grid.ColumnSpan="2"
IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Margin="1" MaxHeight="160" MinHeight="0" Placement="Bottom" MinWidth="{TemplateBinding ActualWidth}" >
<Border x:Name="dropDownBorder" BorderBrush="#e0e0e0" BorderThickness="1" Background="White">
<ScrollViewer x:Name="DropDownScrollViewer" >
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top"
Width="0">
<Rectangle x:Name="opaqueRect"
Fill="{Binding Background, ElementName=dropDownBorder}"
Height="{Binding ActualHeight, ElementName=dropDownBorder}"
Width="{Binding ActualWidth, ElementName=dropDownBorder}" />
</Canvas>
<VirtualizingStackPanel IsItemsHost="True" Orientation="Vertical" VirtualizationMode="Recycling" IsVirtualizing="True" x:Name="ItemsPresenter"
KeyboardNavigation.DirectionalNavigation="Contained"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
</VirtualizingStackPanel>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</VirtualizingStackPanel>
<ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" Grid.ColumnSpan="2"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Style="{StaticResource ComboBoxToggleButton}" />
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Content="{TemplateBinding SelectionBoxItem}"
ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
IsHitTestVisible="false" Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="#e0e0e0"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="None"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="OverridesDefaultStyle" Value="True">
</Setter>
<Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>
</Style>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True">
</Setter>
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Width" Value="Auto">
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border
Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling">
<ContentPresenter />
</VirtualizingStackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background"
Value="#f0f0f0" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
以下是我将其添加到表单中的方式..
<ComboBox x:Name="GameCombobox" Margin="20,0,18,0" Height="25" ItemsSource="{Binding Games, Mode=OneWay, Source={x:Static ui:Ui.Instance}}" SelectedValue="Name" IsEditable="False">
<ComboBox.ItemTemplate>
<DataTemplate>
<VirtualizingStackPanel Orientation="Vertical" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" Height="45" Width="Auto">
<Label FontFamily="Resources/Fonts/#Lato" FontSize="14px" Foreground="Black" Content="{Binding Name}"/>
<VirtualizingStackPanel Orientation="Horizontal" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True" Margin="0 -5 0 0" >
<Path Margin="5 5 0 0" Fill="Crimson" Data="M 25 12 C 11.667228 12 1.25 24.34375 1.25 24.34375 A 1.0001 1.0001 0 0 0 1.25 25.65625 C 1.25 25.65625 11.667228 38 25 38 C 38.332772 38 48.75 25.65625 48.75 25.65625 A 1.0001 1.0001 0 0 0 48.75 24.34375 C 48.75 24.34375 38.332772 12 25 12 z M 25 14 C 27.627272 14 30.141915 14.544587 32.46875 15.375 C 34.032931 17.140338 35 19.450427 35 22 C 35 27.535732 30.535732 32 25 32 C 19.464268 32 15 27.535732 15 22 C 15 19.45074 15.935707 17.139242 17.5 15.375 C 19.834652 14.538846 22.362198 14 25 14 z M 14.1875 16.84375 C 13.439134 18.407614 13 20.155051 13 22 C 13 28.616268 18.383732 34 25 34 C 31.616268 34 37 28.616268 37 22 C 37 20.163179 36.580282 18.404914 35.84375 16.84375 C 41.492764 19.714987 45.555865 23.87765 46.59375 25 C 44.969234 26.756721 35.970973 36 25 36 C 14.029027 36 5.0307657 26.756721 3.40625 25 C 4.4456392 23.876024 8.5256535 19.715345 14.1875 16.84375 z M 25 17 C 22.238576 17 20 19.238576 20 22 C 20 24.761424 22.238576 27 25 27 C 27.761424 27 30 24.761424 30 22 C 30 19.238576 27.761424 17 25 17 z">
<Path.RenderTransform>
<ScaleTransform ScaleY="0.3" ScaleX="0.3"/>
</Path.RenderTransform>
</Path>
<Label Margin="-30 0 0 0" FontFamily="Resources/Fonts/#Lato" FontSize="14px" Foreground="#959699" Content="{Binding Players}"/>
</VirtualizingStackPanel>
</VirtualizingStackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling"></VirtualizingStackPanel>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
答案 0 :(得分:0)
减速是由于DataTemplate
的{{1}} ItemsTemplate
非常“{1}}造成的。即使你使虚拟化工作,你可能会发现ComboBox
这么大的滚动速度很慢,因为所有这些UI对象都将被实例化并呈现,然后在每次实现项目和虚拟化时分别处理。您可以做一些事情来使它“更轻”(更少和更简单的视觉对象),但仍然具有相同的外观。
DataTemplate
内的VirtualizingStackPanels
完全没必要。如果你想要虚拟化,你不要把这些“放在任何地方”,你把它们放在一个非常具体的位置:DataTemplate
用于你正在使用的ItemsPanelTemplate
(在这种情况下是ItemsControl
)ComboBox
代替TextBlock
(这也可以消除您对负边距的需求)Label
绘图正在为ComboBox中的每个项目实例化并重新渲染。不要将其放在Path
内,而是将该复杂DataTemplate
的{{1}}作为静态资源创建,并将其用作简单的填充VisualBrush
。由于Brushes是“freezable”,因此可以重用它们,Path
只会被实例化并呈现一次。我的猜测是Rectangle
可能是你所看到的绝大部分糟糕表现的罪魁祸首(VisualStudio中的分析会告诉你究竟是什么东西需要这么长时间才能进行布局/渲染)。只渲染一次而不是800次,应该会有很多帮助。您的VisualBrush(在某处定义为StaticResource):
Path
然后你的ComboBox:
Path
您可能需要使用一些边距,以及VisualBrush的ViewBox和ViewPort的大小以及矩形的宽度/高度,以使其看起来与您之前的模板完全相同。我没有方便的XAML渲染器来确切了解你的用途。