我的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事件来实现。但是,无法实现上述功能,因为它仅将分配给listview的高度与指针高度匹配,因此将不会工作,因为scrollviewer的高度可以变化。我什至试图访问scrollviewer,但是不能!
我还引用了以下URL:How do I allow a UWP ListView to scroll past the last item? && 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
但是在我的情况下,它们实际上都没有起作用。
我试图找到一个实现此功能的事件,但没有找到任何事件。
任何人都可以提出有关如何检测列表视图滚动是否到达末尾(列表视图中的最后一项)的想法吗?
请注意,我正在Windows 10 UWP应用程序上工作且未获胜8
答案 0 :(得分:1)
好吧,这有点不同,它使用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"
然后...,代码:
首先是一个可观察的自定义集合:这也是您的加载例程:
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
}
}
可以找到更多信息here