WP 8.1 ISupportIncrementalLoading LoadMoreItemsAsync keeps getting called indefinitely

I am trying to implement infinite scrolling using the following example

http://www.davidbritch.com/2014/05/data-virtualisation-using.html

The problem is, in my case, LoadMoreItemsAsync keeps getting called infinitely . I am developing this on a hub (not sure if it matters) and using MVVMLight. Below is my code

.xaml

<Page
x:Class="MyFileServer.UniversalApp.AppHubPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyFileServer.UniversalApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
DataContext="{Binding Source={StaticResource MFSViewModelLocator}, Path=AppHub}">

<Grid>
    <Hub Header="My File Server">
        <HubSection x:Name="MFSNotifications" Header="Notifications">
            <DataTemplate>
                <StackPanel>
                    <ListView x:Name="Notifications"  ItemsSource="{Binding IncrementalNotifications}" >
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding NotificationDescription}"/>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </StackPanel>
            </DataTemplate>
        </HubSection>
        <HubSection x:Name="MFSFiles" Header="Files"></HubSection>
    </Hub>
</Grid>

      

Below is my implementation of ISupportIncrementalLoading

public class IncrementalLoadingNotificationsCollection : ObservableCollection<MFSNotificationModel>, ISupportIncrementalLoading
{
    private INotificationService _notificationService;
    public IncrementalLoadingNotificationsCollection(INotificationService notificationService)
    {
        HasMoreItems = true;
        _notificationService = notificationService;
    }


    public bool HasMoreItems
    {
        get;
        private set;
    }

    public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
    {
        return InnerLoadMoreItemsAsync(count).AsAsyncOperation();
    }

    private async Task<LoadMoreItemsResult> InnerLoadMoreItemsAsync(uint expectedCount)
    {
        var actualCount = 0;
        IList<MFSNotificationModel> notifications;

        try
        {
            notifications = await _notificationService.GetNotificationsAsync(ConfigurationSettings.AccessToken, 8);
        }
        catch (Exception)
        {
            HasMoreItems = false;
            throw;
        }

        if (notifications != null && notifications.Any())
        {
            foreach (var notification in notifications)
            {
                Add(notification);
            }

            actualCount += notifications.Count;
            //_photoStartIndex += (uint)actualCount;
        }
        else
        {
            HasMoreItems = false;
        }

        return new LoadMoreItemsResult
        {
            Count = (uint)actualCount
        };
    }
}

      

Following is an excerpt from viewmodel

public IncrementalLoadingNotificationsCollection IncrementalNotifications
{
    get
    {
        return _incrementalNotifications;
    }
    set
    {
        _incrementalNotifications = value;                
        if (!Equals(null) && _incrementalNotifications.Count > 0)
        {
            DispatcherHelper.CheckBeginInvokeOnUI(() =>
            {
                RaisePropertyChanged(() => IncrementalNotifications);
            });
        }
    }
}

      

Any help to fix this issue is greatly appreciated.

+3


source to share


2 answers


After the game, I managed to solve it. The problem was with the StackPanel, which was the ListView. I don't know why, but somehow the existence of the StackPanel caused LoadMoreItemsAsync to call infinitely and once I removed it it worked fine.



+2


source


As you mentioned in your answer, StackPanel was the culprit. The StackPanel control will not limit the size of its content. This means that if the ListView is loading more items, the height of the ListView will also grow inside the StackPanel, so the ListView thinks each item is visible, so it loads more items, etc.

This also affects virtualization, which is another reason why you should never put a ListView inside a StackPanel. According to the docs :

When the ItemsControl viewport is unlimited, the control does not virtualize. Instead, it creates a product container for each item in its collection. Some common containers that do not limit the size of the viewport are Canvas, StackPanel, and ScrollViewer. You can enable virtualization in this situation by setting the size of the ItemsControl directly instead of allowing it to be sized to fit its parent container.



So your options are:

  • Don't use a StackPanel container. Use a grid instead.
  • If you want to use a StackPanel container, you have to manually set the size (height) of the ListView.
+6


source







All Articles