[英]WPF UI Thread blocked with large collection
我有一個使用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能夠快速處理,還是我錯過了一些增加渲染時間的東西? 我確實認為擁有SharedSizeGroup
的SharedSizeGroup可能是罪魁禍首,但刪除並沒有提高性能。
謝謝。
考慮為您的ItemsControl添加虛擬化。 這樣它只能在視圖中呈現項目而不是所有項目。
<ItemsControl VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我相信你還需要從StackPanel和ScrollViewer中刪除ItemsControl,因為它們會給ItemsControl提供無限的渲染空間,並使虛擬化變得毫無用處。
我看到你正在為你的ItemsPanelTemplate使用WrapPanel,所以你可能需要滾動自己的虛擬化面板,或者檢查一些其他 控件 (我自己沒有使用過)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.