我正在设计类似NetFlix主页的页面。它有许多(20+)GirdView
(启用一行)嵌套在外部ListView
中。所有项目都是不确定的,因此必须在运行时生成。
所以我设计如下:
<Page.Resources>
<DataTemplate x:Key="FirstLevelListViewItemTemplate" x:DataType="model:CategoriesItem">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{x:Bind CategoryName}" FontSize="28"/>
<GridView
Grid.Row="1"
Height="200"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollMode="Disabled"
ItemsSource="{x:Bind categories, Mode=OneWay}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Vertical"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate x:DataType="model:CategoryItem">
<controls:ImageEx IsCacheEnabled="True" Width="250" Source="{x:Bind cover_image_url}"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</DataTemplate>
</Page.Resources>
<!--<ScrollViewer>-->
<ListView x:Name="list"
SelectionMode="None"
ItemTemplate="{StaticResource FirstLevelListViewItemTemplate}">
<!--Disable ListView UI virtualization-->
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<!--</ScrollViewer>-->
public class CategoriesItem
{
public string CategoryName { get; set; }
public List<CategoryItem> categories { get; set; }
}
public class CategoryItem
{
public string cover_image_url { get; set; }
}
用于从本地加载数据:
list.ItemsSource = await GetData();
所以
在启用ListView
的用户界面虚拟化的情况下运行应用程序,绑定过程非常快,内存约为300MB。然后,使用鼠标快速上下滚动ListView,ListView
会非常缓慢地上下滚动,并在屏幕空白后非常慢地显示数据。
在禁用ListView
的用户界面虚拟化的情况下运行应用程序,这一次绑定过程需要很长时间,并且内存可能会增加到1GB。但是快速向上/向下滚动ListView都可以。
答案 0 :(得分:0)
我希望实时树形图显示所有ListViewItem,因为我将使用所有ListViewItem做一些额外的事情。
为解释这种行为,我们可以参考UI virtualization,UI虚拟化是您可以做出的最重要的改进。
这意味着代表项目的UI元素是按需创建的。对于绑定到1000个项目集合的项目控件,同时创建所有项目的UI会浪费资源,因为无法同时显示所有项目。 ListView和GridView(以及其他标准ItemsControl派生的控件)为您执行UI虚拟化。当项目几乎要滚动到视图中(几页之遥)时,框架会为这些项目生成UI并将其缓存。当不太可能再次显示这些项目时,框架会重新占用内存。
您可以将更改ItemsPanelTemplate
更改为StackPanel
来关闭它
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
绑定过程快速且内存不足。
您可以进行数据虚拟化,将json数据切成片,然后使用ListView LoadMoreItemsAsync
加载更多数据。