如何有选择地在Canvas中加载大量控件

时间:2012-01-28 04:49:02

标签: wpf performance virtualization ui-virtualization

我有一个大尺寸的Canvas和很多小的用户控件放在它上面。一次只有一小部分画布在屏幕上可见。用户控件由ItemsControl创建,ItemsControl是绑定到ViewModel的Data。

<Canvas Height="10000" Width="10000" Background="White" >
    <ItemsControl ItemsSource="{Binding Path=MyData}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Views:MyControl />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left" Value="{Binding Left}"/>
                <Setter Property="Canvas.Top" Value="{Binding Top}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</Canvas>

现在由于用户控件的数量巨大,因此加载整个画布需要花费大量时间。我想只加载当前可见帧中的那些控件。如果我移动画布,则应加载新可见区域下的用户控件。我想要这样做的主要原因是与加载大量用户控件相关的性能滞后。我想在Canvas中实现VirtualizingStackPanel对StackPanel的作用。

有办法吗?

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

首先,测试加载空白用户控件。这是用户控件,根本不显示任何内容。如果这足够快,它会告诉我们问题不在画布中处理大量用户控件但是在初始化用户控件时。

因此,如果是这种情况,请创建一个简单的占位符用户控件,在IsVisibleChanged事件触发时使用自身作为画布加载目标用户控件。

全部取决于第一次测试。

答案 1 :(得分:0)

了解虚拟化。使用带有您自己的VirtualizingPanel实现的ListBox,而不是使用Canvas,它可以像Canvas一样工作,只会创建应该可见的控件。

UI虚拟化有很多很好的资源,这里有两个快速选择: