5

J'essaie de créer une application de référence Win8 Metro pour les listes virtualisées. En faisant une lecture (très clairsemée), j'ai trouvé que la façon recommandée de supporter ceci est à travers l'interface ISupportIncrementalLoading.ISupportIncrementalLoading ne déclenche qu'une seule fois

J'ai un problème avec mon application de référence, où la méthode LoadMoreItemsAsync est appelée une seule fois, mais n'est pas appelée à nouveau, même si ma propriété HasmoreItems est codée en dur pour renvoyer True.

Ce que le code ci-dessous doit faire est de charger 40 éléments, puis charger le nombre 'x' à la fois après. Qu'est-ce qui se passe est qu'il charge les 40 premiers éléments, puis est invité à charger 42 de plus, puis n'est jamais demandé de charger à nouveau.

est ici les parties pertinentes de mon 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> 

Classes ViewModel et soutien:

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


} 

}

Répondre

2

Le problème est que votre méthode LoadDataAsync (nombre uint) manque l'opérateur await et en raison de ce qu'il se déroulera de façon synchrone. J'ai eu un problème similaire. La virtualisation des données fonctionnait pour moi pendant que je recevais des dossiers de bibliothèque, mais elle ne s'est déclenchée qu'une seule fois lorsque j'ai essayé de charger une collection d'éléments personnalisés.

J'ai utilisé une solution de contournement, pas très élégant mais cela a fonctionné. Modifier votre méthode LoadDataAsync comme ceci:

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

Eh bien, shucks. Ça marche. Je me demande s'ils vont résoudre ça dans la RC ... – Robaticus

0

L'interface utilisateur n'appeler HasMoreItems quand il se sent il faut. S'il a suffisamment d'éléments pour remplir la zone actuellement visible, il ne vérifiera pas d'autres éléments. Si vous commencez à faire défiler vers la fin de la liste, il vérifiera s'il y a plus d'éléments (et s'il y a appel LoadMoreItemsAsync).

En aparté, vous pouvez simplifier votre code LoadMoreItemsAsync à

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

Merci pour la simplification. Le problème ici est que, pendant que je défile, la charge n'est appelée qu'une seule fois. Je peux aller jusqu'au bout de la liste, après le premier chargement d'objets supplémentaires, et ça ne se déclenche plus jamais. – Robaticus

+0

Ok, le xaml est-il l'intégralité de votre vue? D'autres problèmes peuvent inclure si vous avez votre ListView à l'intérieur d'un ScrollViewer vous n'obtiendrez pas de déclencheurs de virtualisation de données (car cela dépend de l'utilisation du ScrollViewer interne de List Views). –

+0

C'est l'intégralité, à l'exception de la balise '' qui l'entoure. Dois-je faire quelque chose de spécifique dans mon action de chargement asynchrone pour indiquer à ListView que j'ai terminé le chargement, afin qu'il ne se déclenche plus? Je supposais que le retour de LoadMoreItemsResult serait tout ce dont il avait vraiment besoin. – Robaticus

Questions connexes