【问题标题】:List box with over 100 items crashes包含 100 多个项目的列表框崩溃
【发布时间】:2014-06-11 14:42:55
【问题描述】:

我正在开发 windows phone 8 应用程序。

我有一个包含 200 多个项目的列表框要显示。

<DataTemplate x:Key="DataTemplate1">
            <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Border Grid.Row="0" Background="White" Height="400" Width="400" CornerRadius="30,30,30,30">
                </Border>
                <Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Top">
                    <TextBlock HorizontalAlignment="Center" 
                               VerticalAlignment="Center"
                               Margin="5,20,5,5"
                               Foreground="#000000"
                               Text="{Binding Title}"/>
                </Grid>

            </Grid>
        </DataTemplate>

但是它崩溃了,我已经调试了它直到 100 个项目它工作但之后它崩溃了。

PhoneApplicationPage_Loaded 方法中我有

private void PhoneApplicationPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
myList.Add(new MyObject("A","A value"));
            myList.Add(new MyObject("B", "B value"));
            myList.Add(new MyObject("C", "C value"));

and so on... 200 items

ListBoxItems.ItemsSource = myList;
}

我该如何解决这个问题?

更新:

<ItemsPanelTemplate x:Key="ItemsPanelTemplate">
            <local:CollectionFlowPanel ItemHeight="400" 
                                       ItemWidth="400"
                                       FocusedItemOffset="120" 
                                       UnfocusedItemOffset="20" 
                                       ItemVisibility="5">
                <VirtualizingStackPanel />
            </local:CollectionFlowPanel>
        </ItemsPanelTemplate>
    </phone:PhoneApplicationPage.Resources>

    <Grid x:Name="LayoutRoot" Background="#000000">
        <local:CollectionFlow x:Name="ListBoxItems"
                              ItemTemplate="{StaticResource DataTemplate}" 
                              ItemsPanel="{StaticResource ItemsPanelTemplate}"/>
    </Grid>

【问题讨论】:

  • 崩溃显示的错误是什么?
  • @NicholasV。有时它会显示Out of Memory error

标签: c# windows-phone-8 listbox windows-phone listboxitems


【解决方案1】:

确保您在列表框的 ItemsPanelTemplate 中有 VirtualizingStackPanel,see this answer for more info

这是您的 ListBox 可能需要的 XAML:

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <VirtualizingStackPanel />
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>

【讨论】:

  • 但这对 200 多个项目的应用程序崩溃有何影响?
  • GUI 元素不是免费的。它们由 GPU 上的纹理内存支持,因此非常昂贵。 Windows Phone 设备内部的高通系统芯片没有专用的 GPU 芯片(它是集成的),也没有专用的视频 RAM(CPU、GPU 和 DSP 都使用系统 RAM)。我怀疑您的 200 个元素,每个 400 像素,由于 GPU 想要为您的 GUI 元素分配太多纹理,您的系统内存不足。使用 VirtualizingStackPanel,只需创建几个可视元素,并在您滚动列表时重复使用它们来显示不同的项目。
  • 好的,我不知道,你能帮我在我需要的地方添加它吗?如果我将边框宽度和高度设置为 200,它会显示没有任何错误,我还做了一件事,但如果它是 400,它会给我 OOM。为什么会这样?有什么想法吗?
  • 如果需要,我可以将我拥有的整个 POC 发送给您吗?我送你吗?
  • “我需要在我的情况下添加它” - 请参阅更新。 “为什么这样?” — 因为 RAM 的数量与纹理的宽度*高度成正比。当您增加元素的总面积时,您需要更多内存用于纹理。
【解决方案2】:

您需要阅读以下来自 msdn 的关于列表和网格中数据可视化的博客。

Using virtualization with a list or grid

如果没有看到您的整个 xaml 代码,我无法给出确切的答案,但我猜您在 xaml ListBox 中被放置在画布/StackPanel 或滚动查看器控件中。

当 ItemsControl 的视口大小不受限制时,控件不会执行虚拟化。相反,它为其集合中的每个项目创建一个项目容器。一些不限制视口大小的常见容器是 Canvas、StackPanel 和 ScrollViewer。在这种情况下,您可以通过直接设置 ItemsControl 的大小来启用虚拟化,而不是让它由其父容器调整大小。 在这里,我们在 GridView 上设置高度和宽度。这限制了视口的大小,并且视口之外的项目被虚拟化。

以下是两种情况,一种会抛出内存异常,另一种会正常工作(使用相同的代码并进行测试)

1.画布中的列表框

 <Canvas .....
    <ListBox Name="ListBoxItems".....
    </ListBox>
 </Canvas>

上面的代码将抛出内存异常,因为项目控件的视口没有定义(如果你仍然想使用画布而不是定义宽度/高度,如果 ListBox 在这种情况下定义了项目控件的端口并且虚拟化将适用)

2。网格中的列表框

  <Grid .....
    <ListBox Name="ListBoxItems".....
    </ListBox>
 </Grid>

上面的代码不会抛出内存溢出异常,因为虚拟化是应用在列表框上的。

希望这会有所帮助

【讨论】:

  • 我可以分享我的项目吗?请给我你的邮件ID
  • 我已经发给你了,你能不能请我去聊天室给你解释一下
  • 请查收,我等你的回复
  • 你有没有找到任何解决方案来解决它为什么会发生?
  • 我检查了你的代码....你使用的是自定义面板(不是默认虚拟化的列表控件。用 VirtualizingPanel 继承你的 CollectionFlowPanel 类而不是仅仅使用面板来获得虚拟化的优势。我已经继承了 VirtualizingPanel 并加载了 5000 条记录。现在异常没有出现,但我在主视图上看不到项目。您可以在这些行上检查您的代码。
【解决方案3】:

你的对象有多大?如果您的对象太大,您可能无法一次全部加载。

【讨论】:

  • 里面有200多个项目,是不是因为边框的宽度和高度?因为我将它从 400 减少到 200 它显示但我想要它 400
  • 我的意思是,“MyObject”类型的对象需要多少内存?它大约是您的对象构成的总和。例如,如果您的对象包含 4 个整数,那么您的对象将消耗的内存量是整数大小的四倍。如果您的对象包含视频图片等媒体元素,它可能会消耗大量内存,因此您将遇到此“OutOfMemoryException”。
【解决方案4】:

您是否尝试过使用 for 循环?

public List<Fellow> fellowList { get; set; }

private void PhoneApplicationPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
{

fellowList = new List<Fellow>();

for (int i = 0; i < 2; i++)
{
    Fellow fellow = new Fellow();
    fellow.x = "B" + i;
    fellow.value = "B Value" + i;
    fellowList.Add(fellow);
}
this.DataContext = this;

ListBoxItems.ItemsSource = fellowList;    

}

public class Fellow
{
public string x { get; set; }
public string value { get; set; }
}

希望对您有所帮助..根据您的意愿更改视图模型

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多