我有一个使用MVVM构建的WPF应用程序;其中一个视图包含一组长度在200-500之间的模型,每个模型都映射到RepositoryViewModel并绑定到堆栈面板中的“Repository.xaml”视图。
顶级视图(Main.xaml)如下:
<Window.Resources>
<DataTemplate DataType="{x:Type home:RepositoryViewModel}">
<vw:Repository />
</DataTemplate>
<Window.Resources>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Margin="5 40 5 5">
<StackPanel Orientation="Vertical" Grid.IsSharedSizeScope="True">
<ItemsControl ItemsSource="{Binding Repositories}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</ScrollViewer>
Repository.xaml UserControl如下:
<Grid Margin="5" Visibility="{Binding Model.Visibility}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition SharedSizeGroup="WrapPanelGroup" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1">
<!--Textbox is used to allow user to select the text. Changing to Label does not help with rendering issues-->
<TextBox Background="Transparent" BorderThickness="0" Text="{Binding Model.Name}" IsReadOnly="True"
TextWrapping="Wrap" FontSize="18" MaxWidth="300" />
<TextBox Background="Transparent" BorderThickness="0" Text="{Binding Model.Url}" IsReadOnly="True"
TextWrapping="Wrap" FontSize="8" MaxWidth="300" Foreground="DarkGray" />
</StackPanel>
<Button Grid.Column="2" Content="Checkout" Command="{Binding CheckoutCommand}" Visibility="{Binding Model.SingleCheckoutVisible}"/>
<CheckBox Grid.Column="2" IsChecked="{Binding Model.IsChecked}" Visibility="{Binding Model.BulkCheckoutVisible}"/>
</Grid>
以上工作完全符合我的要求,问题是WPF用于呈现控件的时间 - 每个RepositoryViewModel
被添加到RepositoryViewModel
ObservableCollection
整个在渲染控件时,UI会冻结3-5秒。
在尝试隔离问题时,我注意到通过删除文本框,渲染时间大大减少,但删除文本框上的绑定并没有明显的区别。交换标签的文本框几乎没有什么区别。
集合大小是否只是大到期望WPF能够快速处理,还是我错过了一些增加渲染时间的东西?我确实认为使用MaxWidth SharedSizeGroup
可能是罪魁祸首,但删除并没有提高性能。
感谢。
答案 0 :(得分:3)
了解如何在ItemsControl中添加虚拟化。这样它只会在视图中呈现项目而不是所有项目。
<ItemsControl VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我相信你还需要从StackPanel和ScrollViewer中删除ItemsControl,因为它们会给ItemsControl提供无限空间来呈现,并使虚拟化变得毫无用处。
我看到你正在为你的ItemsPanelTemplate使用WrapPanel,所以你可能需要推出自己的虚拟化面板,或者查看一些other controls(我自己没有使用过这些)。 / p>