2

I have read samples on the internet and some are very hard to learn.

I want to learn how to understand when the ListView is scrolling down and if more data is still available, how I can get the data from the internet while showing a ProgressRing on screen.

For my example, I use JSON to get data from a PHP server, and every request I get 10 items from the database.

If you could please provide an easy to understand sample, it would be very much appreciated.

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
Hamed Hosseini
  • 182
  • 2
  • 13
  • You can implement ISupportIncrementalLoading interface, here is the link https://michelsalib.com/2012/10/21/winrt-how-to-properly-implement-isupportincrementalloading-with-navigation/. If you want more help feel free to ask. – Archana May 09 '16 at 04:36
  • @LovetoCode hard code and dont work get very error . please see my bottom post and say how to get part by part request from url server .thanks – Hamed Hosseini May 09 '16 at 15:09
  • Server should implement pagination also. – Archana May 09 '16 at 15:17
  • Url should accept page number and page size – Archana May 09 '16 at 15:18
  • @LovetoCode thanks but not help me . i need complete code and download this and compare with my code. simple example – Hamed Hosseini May 09 '16 at 17:39
  • Do you have server api(url)which takes page number and returns let's say 10 items? If so I can provide the code – Archana May 09 '16 at 17:57
  • @LovetoCode yes url getting page number with post method.please create and put here to solve problem for anyone to solve this problem for ever . if you create a sample and its easy then i created new version with full impelementation for every one. – Hamed Hosseini May 09 '16 at 19:20
  • You should have added your code in the question not as a answer – Archana May 10 '16 at 03:25
  • How are you calculating lastitem? How much items url returns at a time? – Archana May 10 '16 at 05:29
  • Posted the answer,if it solves please accept the answer – Archana May 10 '16 at 14:26

3 Answers3

2
public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            myListView.ItemsSource = new ItemsDataSource();
        }
    }
    public interface IIncrementalSource<T>
    {
        Task<IEnumerable<T>> GetPagedItems(int pageIndex, int pageSize,string url);
    }

    public class IncrementalLoadingCollection<T, I> : ObservableCollection<I>,
         ISupportIncrementalLoading
         where T : IIncrementalSource<I>, new()
    {
        private T source;
        private int itemsPerPage;
        private bool hasMoreItems;
        private int currentPage=0;
        string url;
        public IncrementalLoadingCollection(string url,int itemsPerPage = 10)
        {
            this.source = new T();
            this.itemsPerPage = itemsPerPage;
            this.hasMoreItems = true;
            this.url = url;
        }

        public bool HasMoreItems
        {
            get { return hasMoreItems; }
        }

        public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {
            var dispatcher = Window.Current.Dispatcher;

            return Task.Run<LoadMoreItemsResult>(
                async () =>
                {
                    uint resultCount = 0;
                    var result = await source.GetPagedItems(currentPage++, itemsPerPage,url);

                    if (result == null || result.Count() == 0)
                    {
                        hasMoreItems = false;
                    }
                    else
                    {
                        resultCount = (uint)result.Count();

                        await dispatcher.RunAsync(
                            CoreDispatcherPriority.Normal,
                            () =>
                            {
                                foreach (I item in result)
                                    this.Add(item);
                            });
                    }

                    return new LoadMoreItemsResult() { Count = resultCount };

                }).AsAsyncOperation<LoadMoreItemsResult>();
        }
    }
    public class StructList
    {
        public string Name { get; set; }
    }
    public class ItemsDataSource : IIncrementalSource<StructList>
    {
        private List<StructList> persons;

        public ItemsDataSource()
        {
            persons = new List<StructList>();

            //for (int i = 0; i < 1024; i++)
           // {
            //    var p = new StructList { Name = "Person " + i };
           //     persons.Add(p);
           // }
        }

        public async Task<IEnumerable<StructList>> GetPagedItems(int pageIndex, int pageSize,string url)
        {

            if (persons.Count > 10000) //you wriiten   if (lastItem == 10000),assuming max items 10000
                return null;
            //If you want only 10 items and url returns more than 10 at a time     
            var result = (from p in persons
                          select p).Skip(pageIndex * pageSize).Take(pageSize);
            if (result == null)
            {
                List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
                postData.Add(new KeyValuePair<string, string>("part", pageIndex.ToString()));
                string JSonData = await WebService.get_post_respone(url, postData);
                var items = JsonConvert.DeserializeObject<List<StructList>>(JSonData);
                foreach (var item in items)
                    persons.Add(item);

                return await Task.Run<IEnumerable<StructList>>(() =>
                {
                    result = (from p in persons
                              select p).Skip(pageIndex * pageSize).Take(pageSize);

                    return result;
                });
            }
            else
                return result;
        }
    }

For more information Refer this Link

Archana
  • 3,213
  • 1
  • 15
  • 21
1

i find a way to load data with ISupportIncrementalLoading interface and my problem is how can tell to listview to get every 10 item per page.

how can say to download next part

this is my code in class .

structList is class model for objects.

  public sealed partial class MainPage : Page
    {
        public string category;

        public MainPage()
        {
            this.InitializeComponent();
        }
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
         
            myListView.ItemsSource = new ItemsDataSource();
        }  


 }


  class ItemsDataSource : ObservableCollection<StructList>, ISupportIncrementalLoading
    {
        public int lastItem = 0;
  public string part =0;
    

        public bool HasMoreItems
        {
            get
            {
                if (lastItem == 10000)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }

        public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {


            CoreDispatcher coreDispatcher = Window.Current.Dispatcher;

            return Task.Run<LoadMoreItemsResult>(async () =>
            {
                await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                   
                    });

     
     //get data by part 
     //part in my server start with 0 and later 1,2,3...
      List<StructList> items = new List<StructList>();
                    List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
                    postData.Add(new KeyValuePair<string, string>("part", part));
                    string JSonData = await WebService.get_post_respone(url, postData);
                    items = JsonConvert.DeserializeObject<List<StructList>>(JSonData);
                   
                
                await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                        foreach (StructList item in items)
                        {
                            this.Add(item);
                        }
                    });

                return new LoadMoreItemsResult() { Count =count };
            }).AsAsyncOperation<LoadMoreItemsResult>();
        }
    }
Hamed Hosseini
  • 182
  • 2
  • 13
0

You can use

    <ScrollViewer x:Name="scrollViewer"
                 Loaded="scrollViewer_Loaded"
                  ViewChanged="scrollViewer_ViewChanged">

        <StackPanel Orientation="Vertical">
            <ProgressRing IsActive="{x:Bind IsPullRefresh,Mode=OneWay}" Height="30"></ProgressRing>
            <ListView x:Name="list" ItemsSource="{x:Bind Items}" ></ListView>
        </StackPanel>

    </ScrollViewer>
</Grid>



public sealed partial class MainPage : Page, INotifyPropertyChanged
{
    public ObservableCollection<object> Items { get; set; }

    public bool IsPullRefresh
    {
        get
        {
            return _isPullRefresh;
        }

        set
        {
            _isPullRefresh = value;
            OnPropertyChanged(nameof(IsPullRefresh));
        }
    }

    bool _isPullRefresh = false;

    public MainPage()
    {
        this.InitializeComponent();

        Items = new ObservableCollection<object>();
        for (int i = 0; i < 40; i++)
        {
            Items.Add(i);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string name)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    private void scrollViewer_Loaded(object sender, RoutedEventArgs e)
    {
        scrollViewer.ChangeView(null, 30, null);
    }

    private async void scrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
    {
        var sv = sender as ScrollViewer;

        if (!e.IsIntermediate)
        {
            if (sv.VerticalOffset == 0.0)
            {
                IsPullRefresh = true;
                await Task.Delay(2000);
                for (int i = 0; i < 5; i++)
                {
                    Items.Insert(0, i);
                }
                sv.ChangeView(null, 30, null);
            }
            IsPullRefresh = false;
        }
    }
}

If you can see Chinese,http://www.cnblogs.com/manupstairs/p/5184386.html

lindexi
  • 4,182
  • 3
  • 19
  • 65