c# - 当列表视图滚动到最后一项/无限滚动列表视图时,UWP 列表视图加载更多数据
问题描述
我的 UWP (Windows 10) 应用程序中有一个列表视图。理想情况下,它会在应用程序启动时加载 100 个项目。
当列表滚动到底部,即列表视图中的最后一项时,API 调用将继续并加载另外 100 个项目等等。
这是我的代码:
<ListView x:Name="lstSuggestions" Height="200" Width="250" Foreground="#333eb4" HorizontalAlignment="Left" Margin="60,10" SelectionChanged="lstSuggestions_SelectionChanged"></ListView>
以下调用绑定列表视图(应用程序启动时的前 100 个项目):
public async void GetData(string Id, string limit)
{
string mainUrlForSuggestions = ApiUrl + "&id=" + d;
string finalSelCharas = "";
using (var httpClient = new HttpClient())
{
var dataUri = await httpClient.GetStringAsync(mainUrlForSuggestions);
JsonObject jsonObject = JsonObject.Parse(dataUri.ToString());
JsonArray jsonArray = jsonObject["payload"].GetArray();
foreach (JsonValue groupValue in jsonArray)
{
JsonObject groupObject = groupValue.GetObject();
lstSuggestionsAdd.Add(new SuggestedWords { Name = groupObject.GetNamedString("sug_name"), ID = groupObject.GetNamedString("id") });
}
lstSuggestions.ItemsSource = lstSuggestionsAdd;
}
}
on app start limit 是 100,一旦列表结束,它必须将限制设置为 200 或下 100 个项目并再次进行 API 调用。
我试图通过 pointerEntered 事件来实现这一点。但是,无法实现上述功能,因为它仅将分配给列表视图的高度与指针高度相匹配,因此当滚动查看器高度可能变化时,它不会起作用。我什至试图访问scrollviewer,但不能!
我还提到了以下 URL:如何允许 UWP ListView 滚动过去最后一项? && 检测 WPF listview 滚动条何时位于底部? && https://social.msdn.microsoft.com/Forums/windows/en-US/63b4b530-61d8-477f-af96-87e33260c919/uwa-how-to-detect-the-end-and-the-start-of -listview-and-load-more-data-items?forum=wpdevelop
但在我的情况下,它们都没有真正起作用。
我试图找到一个事件来实现这个功能,但没有找到。
谁能给出一个关于如何检测列表视图滚动是否结束(列表视图中的最后一项)的想法???
请注意,我正在使用 Windows 10 UWP 应用程序而不是 win 8
解决方案
好的,有点不同,它使用 ListView 的incremental loading
功能来创建无限滚动列表。
这意味着您不会像您在问题中假设的那样控制加载数据,但我仍然认为它会满足您的需求:
它使用一些 MVVM 绑定,因此实际上没有使用任何事件。如果您对MVVM不了解,请尝试了解一下。
首先是一些 XAML,默认主页:
<Page
x:Class="App6.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App6"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:ViewModel, IsDesignTimeCreatable=True}">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding Items}"
DataFetchSize="1"
IncrementalLoadingTrigger="Edge"
IncrementalLoadingThreshold="5">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Text}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
注意
ItemsSource="{Binding Items}"
DataFetchSize="1"
IncrementalLoadingTrigger="Edge"
IncrementalLoadingThreshold="5"
- ItemSource 将绑定到项目集合,它在项目模板中使用
- DataFetchSize,到达末尾时要获取的数量:以 PAGES 为单位。(让我困惑了一会儿)
- IncrementalLoadingTrigger,见msdn
- IncrementalLoadingThreshold,见msdn
然后...,代码:
首先是一个自定义的 observable 集合:这也是你的加载例程:
public class IncrementalLoadingCollection : ObservableCollection<Item>, ISupportIncrementalLoading
{
uint x = 0; //just for the example
public bool HasMoreItems { get { return x < 10000; } } //maximum
//the count is the number requested
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
{
return AsyncInfo.Run(async cancelToken =>
{
//here you need to do your loading
for (var c = x; c < x + count; c++)
{
//add your newly loaded item to the collection
Add(new Item()
{
Text = c.ToString()
});
}
x += count;
//return the actual number of items loaded (here it's just maxed)
return new LoadMoreItemsResult { Count = count };
});
}
}
我们正在使用一个new Item
类,所以让我们定义它:
//the type which is being used to display the data
//you could extend it to use images and stuff
public class Item
{
public string Text { get; set; }
}
让我们创建一个视图模型:
public class ViewModel
{
public ViewModel()
{
Items = new IncrementalLoadingCollection();
}
//using the custom collection: these are your loaded items
public IncrementalLoadingCollection Items { get; set; }
}
将其包装在后面的代码中:我们使用数据上下文:
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataContext= new ViewModel(); //using a viewmodel as data context
}
}
更多信息可以在这里找到
推荐阅读
- python - 如何从 csv 文件中过滤数据并合并所有过滤后的数据?
- mysql - JOIN BY 公司 Big SQL 查询
- r - How to convert x values from dbeta plot into percentage using base r?
- python - 是否可以在文档字符串中包含常量的值?
- java - 添加 NULLS LAST 时的问题
- c# - 自定义属性的命名约定和准则
- python - 获取异常消息的更好方法是:str(e) vs e.args[0]?
- java - 使用 spring boot 和 hibernate 执行多个不同的查询
- c++ - 为什么我的 TensorFlow Serving 使用 bazel build copt avx2 无助于加快推理速度?
- python-3.x - 参考基于python中其他文件的公共信息过滤的文件创建文件