Question

I'm trying to create a Win8 Metro reference app for virtualized lists. In doing some (very sparse) reading, I've found that the recommended way of supporting this is through the ISupportIncrementalLoading interface.

I'm having a problem with my reference app, where the LoadMoreItemsAsync method is called once, but isn't called again, even though my HasmoreItems property is hard coded to return True.

What the code below should do is load 40 items, then load 'x' number at a time afterwards. What happens is that it loads the first 40 items, then is prompted to load 42 more, then is never asked to load again.

Here's the relevant portions of my code:

XAML

<Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
    <ListView ItemsSource="{Binding Items}" Width="800" HorizontalAlignment="Left" Margin="12">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Title}" Foreground="White"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</Grid>

ViewModel and Support Classes:

public class MainViewModel : ViewModelBase
{

    public MyIncrementalCollection Items { get; set; }

    public MainViewModel()
    {

        Items = new MyIncrementalCollection();



        for (int i = 0; i < 40; i++)
        {
            Items.Add(new MyData {Title = string.Format("Item: {0}", i)});
        }
    }
}

public class MyData
{
    public string Title { get; set; }
}

public class MyIncrementalCollection : ObservableCollection<MyData>, ISupportIncrementalLoading
{
    public bool HasMoreItems
    {
        get
        {
            return true;
        }
    }

    public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
    {
        return
            (IAsyncOperation<LoadMoreItemsResult>)
            AsyncInfo.Run((System.Threading.CancellationToken ct) => LoadDataAsync(count));
    }

    private async Task<LoadMoreItemsResult> LoadDataAsync(uint count)
    {

        for (int i = 0; i < count; i++)
        {
            this.Add(new MyData { Title = string.Format("Item: {0}, {1}", i, System.DateTime.Now) });
        }

        var ret = new LoadMoreItemsResult {Count = count};

        return ret;
    }


}

}

Was it helpful?

Solution

The problem is that your method LoadDataAsync(uint count) is lacking the await operator and due to that it will run synchronously. I had a similar problem. Data virtualization was working for me while I was receiving some library folders but it was triggered only once when I tried to load a collection of custom items.

I used a workaround, not very elegant but it worked. Modify your LoadDataAsync method like this:

private async Task<LoadMoreItemsResult> LoadDataAsync(uint count)
{
  Task task = Task.Delay( 1 );
  await task;

  for (int i = 0; i < count; i++)
  {
    Add(new MyData { Title = string.Format("Item: {0}, {1}", i, System.DateTime.Now) });
  }

  return new LoadMoreItemsResult {Count = count};
}

OTHER TIPS

The UI will only call HasMoreItems when it feels it needs to. If it has enough items to fill the currently viewable area then it won't check for more items. If you start to scroll towards the end of the list then it will check to see if there are more items (and if there are call LoadMoreItemsAsync).

As an aside you can simplify your code in LoadMoreItemsAsync to

public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
{
    return LoadDataAsync(count).AsAsyncOperation();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top