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;
    }


}

}

Était-ce utile?

La 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};
}

Autres conseils

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();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top