2016-02-22 33 views
0

我写一个Windows应用程序8.1,我现在用了很长的GridView。我正在使用UI虚拟化,而视图模型包含一个包含100K项目的可观察集合。ItemsWrapGrid隐藏物品通过偏移

<GridView ItemsSource="{Binding Items}"> 
    <GridView.ItemsPanel> 
     <ItemsPanelTemplate> 
      <ItemsWrapGrid Orientation="Vertical"/> 
     </ItemsPanelTemplate> 
    </GridView.ItemsPanel> 
    <GridView.ItemTemplate> 
     <DataTemplate> 
      <Border 
       Background="LightBlue" 
       Height="200" Width="200" 
       > 
       <TextBlock 
        Text="{Binding Index}" 
        VerticalAlignment="Center" HorizontalAlignment="Center" 
        FontSize="30" 
        /> 
      </Border> 
     </DataTemplate> 
    </GridView.ItemTemplate> 
</GridView> 

在屏幕上,它看起来像这样: enter image description here

当使用默认项面板(ItemsWrapGrid)和朝列表的末尾滚动,在某一时刻开始的项目消失。

enter image description here

我与物品的各种大小进行了测试,并削波总是开始于同一滚动偏移量(约200万个像素)。当我用WrapGrid替换面板时,错误不会发生。据我所知,ItemsWrapGrid具有更好的虚拟化,并想使用它,但这个错误当然是不能接受的。

有没有解决这个错误的方式,同时仍使用ItemsWrapGrid

+0

我可以看看,你可以分享你的代码? – ezaspi

+0

该问题包含您需要的所有代码。只需将数据上下文设置为包含名为Items的属性的任何类,其中包含1000000个对象,您将看到它。 –

+0

视图尝试呈现时,内存不足。也就是说,在我的Observable集合被填充并且xaml视图开始显示之后,我得到System.OutOfMemoryException。你是否正在做任何事情来避免OutOfMemoryException? – ezaspi

回答

1

只是发表我的OutOfMemoryException异常的窘境后,我做了一点点研究,我认为我有你的解决方案,我发现这一点:

视口的概念是UI虚拟化至关重要的,因为框架必须创建可能显示的元素。通常, 控件的视口是逻辑控件的范围。例如,一个ListView的视口是ListView元素的宽度和 的高度。一些面板允许子元素 不受限制的空间,例如ScrollViewer和网格,其中 自动调整大小的行或列。当一个虚拟化的ItemsControl放置 在那样的面板,它需要足够的空间来显示所有其 项,这违背了虚拟化的。通过在ItemsControl上设置 宽度和高度来恢复虚拟化。 ListView and GridView UI optimization

所以我这个添加到你的GridView的ItemsSource:

<GridView ItemsSource="{Binding Items}" VirtualizingStackPanel.VirtualizationMode="Recycling" Width="800" Height="800"> 

它看起来像它需要一个宽度和高度。 enter image description here

+0

谢谢,但GridView坐落在一个有宽度和高度的容器内(它不是一个滚动查看器或任何赋予它无限空间的任何东西)。实际上,虚拟化的作品!我正在使用一种特殊类型的可观察集合,它会懒散地创建它的项目,所以我确信虚拟化本身能够工作(它也回答了您的第一个关于如何避免内存问题的问题)。唯一的问题是它没有呈现通过2000000像素宽度的项目。 –

+0

如何检查“2000000像素宽度”?但是这似乎违背了将像素限制在视口内的视口思想? – ezaspi

+0

无论如何,我认为这很有趣,因为我不需要写点东西来使用虚拟化。我认为微软解释的概念和延迟加载集合是两回事。微软定义的虚拟化似乎旨在避免尝试显示“200万像素”。 – ezaspi