5

Я пытаюсь создать ссылку для ссылки на Win8 Metro для виртуализированных списков. Выполняя некоторые (очень редкие) чтения, я обнаружил, что рекомендуемый способ поддержки этого - через интерфейс ISupportIncrementalLoading.ISupportIncrementalLoading only fire once

У меня проблема с моим справочным приложением, где метод LoadMoreItemsAsync вызывается один раз, но не вызывается снова, хотя свойство HasmoreItems жестко закодировано, чтобы вернуть True.

Что должен сделать следующий код, это загрузить 40 элементов, а затем загрузить «x» число за раз после этого. Что происходит, так это то, что он загружает первые 40 элементов, затем ему предлагается загрузить еще 42, а затем больше не запрашивается загрузка.

Вот соответствующие части моего кода:

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 и Классы поддержки:

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


} 

}

ответ

2

Проблема заключается в том, что ваш метод LoadDataAsync (количество UINT) отсутствует оператор ОЖИДАНИЕ и благодаря тому, что он будет работать синхронно. У меня была аналогичная проблема. Виртуализация данных работала для меня, когда я получал некоторые библиотечные папки, но она запускалась только один раз, когда я пытался загрузить коллекцию настраиваемых элементов.

Я использовал обходное решение, не очень элегантное, но оно сработало. Измените LoadDataAsync метод как это:

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

Ну, шорты. Это работает. Интересно, исправят ли они это в RC ... – Robaticus

0

Пользовательский интерфейс будет вызывать только HasMoreItems, когда он чувствует это необходимо. Если у него достаточно предметов, чтобы заполнить область, просматриваемую в данный момент, она не будет проверять наличие большего количества предметов. Если вы начнете прокрутку в конце списка, тогда он проверит, есть ли больше элементов (и если есть вызов LoadMoreItemsAsync).

Как в стороне вы можете упростить код в LoadMoreItemsAsync для

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

Спасибо за упрощение. Проблема здесь в том, что, когда я прокручиваю, загрузка получает только один раз. Я могу сделать это до конца списка, после первой загрузки дополнительных предметов, и он никогда не срабатывает снова. – Robaticus

+0

Хорошо, это xaml весь ваш взгляд? Другие проблемы могут включать в себя, если у вас есть ListView внутри ScrollViewer, вы не получите триггеры виртуализации данных (поскольку это зависит от использования внутреннего представления ScrollViewer в List Views). –

+0

Это полностью, за исключением тега ''. Должен ли я делать что-то конкретное в моем асинхронном действии загрузки, чтобы сообщить ListView, что я загружен, поэтому он не запускается снова? Я предположил, что возвращение LoadMoreItemsResult будет всем, что действительно нужно. – Robaticus