I have a WPF application built using MVVM; one of the Views contains a collection of models that can be between 200-500 in length, each of the models are mapped to a RepositoryViewModel and bound to the 'Repository.xaml' view in a stack panel.
The top level View (Main.xaml) is as follows:
<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 is as follows:
<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>
The above works perfectly as I require, the issue is the time WPF takes to render the controls- once each of the RepositoryViewModel
's are added to the RepositoryViewModel
ObservableCollection
the entire UI freezes for 3-5 seconds whilst the controls are rendered.
Whilst trying to isolate the issue I noticed that by removing the textbox's the render time dramatically decreases but removing the binding on the textbox's does not make a noticeable difference. Swapping the textbox's for labels made little difference.
Is the collection size simply to large to expect WPF to handle quickly or am I missing something that is increasing the render time? I did consider having a SharedSizeGroup
with a MaxWidth may be the culprit but removing did not improve performance.
Thanks.
Look into adding virtualization to your ItemsControl. This way it only renders the items in view rather than all of them.
I believe you'd also need to remove the ItemsControl from the StackPanel and ScrollViewer, as they'll give the ItemsControl infinite space to render, and render the virtualization useless.
I see you're using a WrapPanel for your ItemsPanelTemplate, so you may need to roll your own virtualized panel, or check out some other controls (haven't used these myself).