WPF UI线程被大集合

时间:2015-11-05 15:13:37

标签: c# wpf xaml mvvm

我有一个使用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可能是罪魁祸首,但删除并没有提高性能。

感谢。

1 个答案:

答案 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>