繁体   English   中英

使用时内存不足异常 <ScrollViewer> 其中有多个ListView

[英]Out of memory exception while using <ScrollViewer> with multiple ListViews in it

我有一个带有2个ListViews的用户控件。 一个用于保存预定义类别的列表,另一个用于包含所有类别的列表。 当我将ListViews放置在<Grid> ,一切都完美无缺。 有效的xaml代码(带有Grid):

<Grid Style="{StaticResource ResourceKey=ContentStyle}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListView x:Name="lstPredefinedCategories" Grid.Row="0" ItemsSource="{Binding PredefinedCategories}" SelectionMode="Multiple" Margin="20">
            <ListView.Header>
                <StackPanel>
                    <TextBlock Text="Voorgestelde categorie&#235;n" Style="{StaticResource TextBlockStyle}" FontWeight="SemiBold" Foreground="Black" />
                    <Rectangle Style="{StaticResource DividerStyle}" Fill="Black"/>
                </StackPanel>
            </ListView.Header>

            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}" Style="{StaticResource TextBlockStyle}" HorizontalAlignment="Left" TextWrapping="Wrap" Width="300" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Grid Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Margin="20,0">
                <TextBlock Text="Alle categorie&#235;n" Style="{StaticResource TextBlockStyle}" FontWeight="SemiBold" Foreground="Black" />
                <Rectangle Style="{StaticResource DividerStyle}" Fill="Black"/>
            </StackPanel>
            <TextBox x:Name="txtSearch" PlaceholderText="Zoek categorie" Grid.Row="1" Style="{StaticResource SearchboxStyle}" Margin="20,0" TextChanged="txtSearch_TextChanged" />
            <Rectangle Grid.Row="2" Style="{StaticResource DividerStyle}" Margin="20, 0" />
            <ListView x:Name="lstCategories" Grid.Row="3" Margin="20,10,20,0" ItemsSource="{Binding Categories}" SelectionMode="Multiple" SelectionChanged="lstCategories_SelectionChanged">

                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Key}" Style="{StaticResource TextBlockStyle}" HorizontalAlignment="Left" TextWrapping="Wrap" Width="300" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <Rectangle Grid.Row="4" Style="{StaticResource DividerStyle}" Margin="20, 0" />
            <Grid Grid.Row="5">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Button x:Name="btnAnnuleren" Grid.Column="0" Content="Annuleren" Style="{StaticResource ButtonAnnulerenStyle}" Click="btnAnnuleren_Click"/>
                <Rectangle Grid.Column="1" Fill="#A9A9A9" Width="0.5" Margin="10,0" />
                <Button x:Name="btnSelecteren" Grid.Column="2" Content="Selecteren" Style="{StaticResource ButtonAnnulerenStyle}" Click="btnSelecteren_Click"/>
            </Grid>
        </Grid>
    </Grid>

唯一的问题是我没有得到想要的UI行为。 如果我使用网格,则只有红色边框是可滚动的(由于ListView)。 但是我需要的是整个绿色边框都是可滚动的。

WP布局

所以我想将所有内容放入<ScrollViewer><StackPanel></StackPanel></ScrollViewer> 但是,当我这样做时,有时会遇到内存不足的异常(有时应用程序会冻结并无例外关闭)。

这是我不使用<ScrollViewer> xaml的方法:

<ScrollViewer>
        <StackPanel>
            <ListView x:Name="lstPredefinedCategories" ItemsSource="{Binding PredefinedCategories}" SelectionMode="Multiple" Margin="20">
                <ListView.Header>
                    <StackPanel>
                        <TextBlock Text="Voorgestelde categorie&#235;n" Style="{StaticResource TextBlockStyle}" FontWeight="SemiBold" Foreground="Black" />
                        <Rectangle Style="{StaticResource DividerStyle}" Fill="Black"/>
                    </StackPanel>
                </ListView.Header>

                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" Style="{StaticResource TextBlockStyle}" HorizontalAlignment="Left" TextWrapping="Wrap" Width="300" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <StackPanel Grid.Row="0" Margin="20,0">
                    <TextBlock Text="Alle categorie&#235;n" Style="{StaticResource TextBlockStyle}" FontWeight="SemiBold" Foreground="Black" />
                    <Rectangle Style="{StaticResource DividerStyle}" Fill="Black"/>
                </StackPanel>
                <TextBox x:Name="txtSearch" PlaceholderText="Zoek categorie" Grid.Row="1" Style="{StaticResource SearchboxStyle}" Margin="20,0" TextChanged="txtSearch_TextChanged" />
                <Rectangle Grid.Row="2" Style="{StaticResource DividerStyle}" Margin="20, 0" />
                <ListView x:Name="lstCategories" Grid.Row="3" Margin="20,10,20,0" ItemsSource="{Binding Categories}" SelectionMode="Multiple" SelectionChanged="lstCategories_SelectionChanged">

                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Key}" Style="{StaticResource TextBlockStyle}" HorizontalAlignment="Left" TextWrapping="Wrap" Width="300" />
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
                <Rectangle Grid.Row="4" Style="{StaticResource DividerStyle}" Margin="20, 0" />
                <Grid Grid.Row="5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Button x:Name="btnAnnuleren" Grid.Column="0" Content="Annuleren" Style="{StaticResource ButtonAnnulerenStyle}" Click="btnAnnuleren_Click"/>
                    <Rectangle Grid.Column="1" Fill="#A9A9A9" Width="0.5" Margin="10,0" />
                    <Button x:Name="btnSelecteren" Grid.Column="2" Content="Selecteren" Style="{StaticResource ButtonAnnulerenStyle}" Click="btnSelecteren_Click"/>
                </Grid>
            </Grid>
        </StackPanel>
    </ScrollViewer>

关于为什么我的应用程序冻结或获得OOM异常有任何想法吗?

更新

这是因为在第二个ListView中,它们加载了太多对象。 因此,我将尝试使用ISupportIncrementalLoading对其进行修复。

还是有其他方法?

解决方案是使用虚拟化(ISupportIncrementalLoading),如注释中所建议。

在这里,您可以找到我的ISupportIncrementalLoading实现类:

public class StringKeyValueIncrementalCollection : ObservableCollection<StringKeyValue>, ISupportIncrementalLoading
    {

        private List<StringKeyValue> allCategories;
        private int lastItem = 1;

        public StringKeyValueIncrementalCollection(List<StringKeyValue> categories)
        {
            this.allCategories = categories;
        }

        public bool HasMoreItems
        {
            get
            {
                if (lastItem == allCategories.Count)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }

        public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {

            CoreDispatcher coreDispatcher = Window.Current.Dispatcher;

            return Task.Run<LoadMoreItemsResult>(async () =>
            {

                List<StringKeyValue> items = new List<StringKeyValue>();
                for (int i = 0; i < count; i++)
                {
                    items.Add(allCategories[i]);
                    lastItem++;
                    Debug.WriteLine(lastItem);
                    if (lastItem == allCategories.Count)
                    {
                        break;
                    }
                }

                await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                        foreach (StringKeyValue item in items)
                        {
                            this.Add(item);
                        }
                    });

                return new LoadMoreItemsResult() { Count = count };
            }).AsAsyncOperation<LoadMoreItemsResult>();
        }
    }

然后我的代码在ViewModel中。 如您所见,我使用StringKeyValueIncrementalCollection代替常规的List<object>

    private StringKeyValueIncrementalCollection categories;
    private StringKeyValueIncrementalCollection allCategories;

    public StringKeyValueIncrementalCollection Categories
    {
        get { return categories; }
        set
        {
            filteredCategories = value;
            RaisePropertyChanged("Categories");
        }
    }
    public async void LoadCategories()
    {
        List<StringKeyValue> temp = await this.openVlaanderenService.GetCategoriesData();
        allCategories = new StringKeyValueIncrementalCollection(temp);
        Categories = allCategories;
    }

您唯一遇到的问题是ScollViewer将允许其内容填充所需的尽可能多的空间,因此数据将继续加载。 要解决此问题,我做了不支持ScrollViewer的ISupportIncrementalLoading中所建议的操作吗?

因此,我向SizeChanged="ScrollViewer_SizeChanged"添加了SizeChanged="ScrollViewer_SizeChanged"事件,并在后面的代码中根据ScrollViewer的视口大小属性设置了ListView的大小:

private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
    lstCategories.Height = scrollViewer.ViewportHeight;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM