【问题标题】:UWP listview load more data when listview scrolling reaches to last item / infinite scrolling listview当列表视图滚动到最后一项/无限滚动列表视图时,UWP 列表视图加载更多数据
【发布时间】:2018-08-08 16:28:44
【问题描述】:

我的 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,但不能!

我还提到了以下网址: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 应用程序而不是 win 8

【问题讨论】:

  • 我们缺少一些信息:1) lstSuggestions_PointerEntered 是什么样的? 2)它被调用了吗? (用断点测试) 3)onitem_visible-like 事件中没有一些吗?
  • @Stefan lstSuggestions_PointerEntered 每当指针移动到列表视图区域/部分时都会被调用。它只是捕获指针是否在列表视图 UI 区域中
  • 我似乎看不出您的实际问题是什么。项目是否添加到列表视图中?如果是这样,您可以将它们滚动到视图中吗?
  • @Stefan 前 100 个项目被添加到列表视图中并且也可以滚动。现在假设如果用户滚动到最后一个项目,我想将接下来的 100 个项目加载到列表视图中。我也提到了同样的问题
  • 我的代码将加载列表视图中的前 100 个项目,一旦列表滚动到最后一个项目/底部,它应该加载另外 100 个项目。在这种情况下,我是否包含lstSuggestions_PointerEntered 并不重要。你可以参考这个答案:[Detect when WPF listview scrollbar is at the bottom? ] (stackoverflow.com/a/37430977/8024811) 但对我来说没有帮助

标签: c# listview uwp windows-10-universal uwp-xaml


【解决方案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"

  1. ItemSource 将绑定到项目集合,在项目模板中使用它
  2. DataFetchSize,到达末尾时要获取的数量:以 PAGES 为单位。 (让我困惑了一会儿)
  3. IncrementalLoadingTrigger,见msdn
  4. 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           
    }
}

更多信息可以找到here

【讨论】:

  • 嘿,感谢您的宝贵意见,我将按照您的建议进行更改。并会在某个时候通知您
  • 注释在哪里://here you need to do your loading,可以删除for循环,用自己的逻辑填充集合
  • API 以这样的方式返回,它只能加载 100 个项目,因为有大量数据,这就是为什么我在我的代码中传递限制参数,就像到达列表末尾一样它将调用一个 API 来加载下一个 100
  • 我可以简单地做lstSuggestions.add(new Item(name, id)) aslstSuggestions 依赖于其他功能。我正在使用lstSuggestions 来实现其他功能。如果我按照您的建议进行更改,那么在这种情况下我将无法使用lstSuggestions
  • 您好,最好提出一个新问题,可能参考这个问题,您会得到充分的关注,并有最好的机会回答您的问题 ;-)
猜你喜欢
  • 2013-01-21
  • 1970-01-01
  • 2014-12-12
  • 2019-12-10
  • 2017-01-28
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
相关资源
最近更新 更多