当列表视图滚动到最后一项/无限滚动列表视图时,UWP 列表视图加载更多数据
UWP listview load more data when listview scrolling reaches to last item / infinite scrolling listview
我的 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;
}
}
应用启动限制为 100,一旦列表结束,它必须将限制设置为 200 或下 100 项并再次调用 API。
我试图通过 pointerEntered 事件来实现这一点。但是,无法实现上述功能,因为它仅将分配给列表视图的高度与指针高度相匹配,因此不会起作用,因为滚动查看器的高度可能会有所不同。我什至试图访问 scrollviewer,但不能!
我还提到了以下 URL 的内容: && Detect when WPF listview scrollbar is at the bottom? && 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
但其中 none 个在我的案例中确实有效。
我试图找到一个事件来实现这个功能,但没有找到。
谁能告诉我如何检测列表视图滚动是否结束(列表视图中的最后一项)???
请注意,我正在开发 windows 10 UWP 应用程序而不是 win 8
好的,有点不同,它使用 ListView 的 incremental loading
功能来创建无限滚动列表。
这意味着您无法像您在问题中假设的那样控制加载数据,但我仍然认为它会满足您的需要:
它使用了一些 MVVM 绑定,因此实际上没有使用任何事件。如果您不了解 MVVM,请尝试 duckduckgo 一点。
先放一些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
那么……,代码:
首先是自定义可观察集合:这也是您的加载例程:
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
class,所以让我们定义它:
//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
}
}
可以找到更多信息here
我的 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;
}
}
应用启动限制为 100,一旦列表结束,它必须将限制设置为 200 或下 100 项并再次调用 API。
我试图通过 pointerEntered 事件来实现这一点。但是,无法实现上述功能,因为它仅将分配给列表视图的高度与指针高度相匹配,因此不会起作用,因为滚动查看器的高度可能会有所不同。我什至试图访问 scrollviewer,但不能!
我还提到了以下 URL 的内容:
但其中 none 个在我的案例中确实有效。
我试图找到一个事件来实现这个功能,但没有找到。
谁能告诉我如何检测列表视图滚动是否结束(列表视图中的最后一项)???
请注意,我正在开发 windows 10 UWP 应用程序而不是 win 8
好的,有点不同,它使用 ListView 的 incremental loading
功能来创建无限滚动列表。
这意味着您无法像您在问题中假设的那样控制加载数据,但我仍然认为它会满足您的需要:
它使用了一些 MVVM 绑定,因此实际上没有使用任何事件。如果您不了解 MVVM,请尝试 duckduckgo 一点。
先放一些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
那么……,代码:
首先是自定义可观察集合:这也是您的加载例程:
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
class,所以让我们定义它:
//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
}
}
可以找到更多信息here