2012-05-10 18 views
5

Sto provando a creare un'app di riferimento Metro Win8 per gli elenchi virtualizzati. Nel fare alcune (molto scarse) letture, ho trovato che il modo consigliato di supportarlo è attraverso l'interfaccia ISupportIncrementalLoading.ISupportIncrementalLoading si attiva solo una volta

Sto riscontrando un problema con la mia app di riferimento, in cui il metodo LoadMoreItemsAsync viene chiamato una volta, ma non viene chiamato di nuovo, anche se la proprietà HasmoreItems è codificata per restituire True.

Ciò che il codice seguente dovrebbe fare è caricare 40 articoli, quindi caricare il numero "x" in un momento successivo. Quello che succede è che carica i primi 40 elementi, quindi viene richiesto di caricarne altri 42, quindi non viene mai chiesto di caricarlo di nuovo.

Ecco le porzioni rilevanti del mio codice:

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 e Supporto Classi:

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


} 

}

risposta

2

Il problema è che il metodo LoadDataAsync (conteggio uint) manca l'operatore await e causa di che verrà eseguito in modo sincrono. Ho avuto un problema simile. La virtualizzazione dei dati stava funzionando per me mentre stavo ricevendo alcune cartelle della libreria, ma è stata attivata solo una volta quando ho provato a caricare una raccolta di elementi personalizzati.

Ho usato una soluzione, non molto elegante ma ha funzionato. Modifica la LoadDataAsync metodo come questo:

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

Beh, manda. Che funzioni. Mi chiedo se sistemeranno questo nella RC ... – Robaticus

0

L'interfaccia utente sarà chiamare soltanto HasMoreItems quando ci si sente ha bisogno di Se ha abbastanza elementi per riempire l'area attualmente visibile, allora non controllerà più elementi. Se inizi a scorrere verso la fine della lista, controllerà se ci sono più elementi (e se ci sono chiamate LoadMoreItemsAsync).

Per inciso è possibile semplificare il codice in LoadMoreItemsAsync per

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

Grazie per la semplificazione. Il problema qui è che, mentre scorro, il carico viene chiamato una sola volta. Posso arrivare fino in fondo alla lista, dopo il primo carico di elementi aggiuntivi, e non si accende mai più. – Robaticus

+0

Ok, l'xaml è l'interezza della tua vista? Altri problemi possono includere se hai il tuo ListView all'interno di un ScrollViewer che non otterrai trigger di virtualizzazione dei dati (dato che dipende dall'uso di ScrollViewer interno di List Views). –

+0

Questo è l'insieme, ad eccezione del tag ''. Devo fare qualcosa di specifico nella mia azione di caricamento asincrono per dire a ListView che ho finito di caricare, quindi non si attiva di nuovo? Supponevo che il ritorno di LoadMoreItemsResult sarebbe stato tutto ciò di cui aveva veramente bisogno. – Robaticus

Problemi correlati