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.
source to share
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.
source to share