6

Con l'ultimo aggiornamento di Windows Phone Toolkit hanno revisionato gli interni di LongListSelector per la versione di Mango. Una delle modifiche è stata la rimozione del supporto per la funzione GetItemsInView() (ora restituisce una lista vuota). Questa funzione ha in precedenza restituito un elenco di elementi che erano attualmente visibili sullo schermo. Stavo usando questo per ottenere un riferimento all'elemento visibile più in alto durante la navigazione lontano da una pagina in modo che potessi supportare il recupero dopo una pietra tombale usando ScrollTo(object item).Aggiornamento del toolkit WP7 Rimosso GetItemsInView() da LongListSelector

Qualcuno sa quale sarebbe l'alternativa suggerita? So che con la rimozione del tombino di Mango è molto meno un problema, ma mi piacerebbe ancora sostenerlo e potrebbero esserci altri scenari in cui vorrei ricordare la posizione di scorrimento. Il mio elenco contiene migliaia di elementi in alcuni casi.

+0

Credo che non è possibile utilizzare un indice elemento selezionato? – jv42

+0

Ci ho pensato, ma è possibile per l'utente scorrere fino a una posizione senza effettuare una selezione. – CactusPCJack

+0

Sta modificando il codice sorgente del Toolkit come un'opzione? So che dovevo farlo per un progetto, c'era un grosso bug di scorrimento. – jv42

risposta

4

Da quello che posso dire dai nuovi bit, è necessario abbonarsi agli eventi Link e Unlink di LLS. Link passerà in un arg che contiene l'elemento aggiunto alla parte visibile del LLS. Unlink fa lo stesso per quegli articoli rimossi dal LLS. Così si farebbe qualcosa di simile:

List<string> trackedItems = new List<string>(); 

private void myListOfStrings_Link(object sender, LinkUnlinkEventArgs e) 
{ 
    var x = e.ContentPresenter; 
    if (x == null || x.Content == null) 
     return; 
    trackedItems.Add(x.Content.ToString()); 
} 

private void myListOfString_Unlink(object sender, LinkUnlinkEventArgs e) 
{ 
    var x = e.ContentPresenter; 
    if (x == null || x.Content == null) 
     return; 
    trackedItems.Remove(x.Content.ToString()); 
} 

noti che Link e Unlink sparerà per ogni elemento reso nella lista sottostante, quindi se si sta utilizzando le funzionalità di raggruppamento dei LLS, allora si dovrà per aumentare il test sull'opportunità o meno di tenere traccia dell'elemento in base a quale tipo viene effettivamente restituito. Quindi, se si dispone di una sorta di oggetto di gruppo per il quale si desidera tenere traccia degli oggetti underrlying, si potrebbe fare qualcosa di simile:

private void myGroupedListOfObjects_Link(object sender, LinkUnlinkEventArgs e) 
{ 
    var x = e.ContentPresenter; 
    if (x == null || x.Content == null) 
     return; 
    var myObject = x.Content as MyObject; 
    if (myObject != null) 
    { 
     foreach (var item in myObject.Items) 
     { 
      trackedItems.Add(item); 
     } 
    } 
} 

Spero che questo aiuta! Facci sapere se funziona.

+0

Molto bello. Sto installando il Mango RC in questo momento o proverei a giocare con le tue idee. In base agli avvisi di ritiro, questo è il tipo di risposta che mi aspettavo. La mia unica domanda successiva è, come si può determinare (con link e scollegare) quale elemento è più in alto? Sembra che tu debba sapere in quale direzione stavano scorrendo. – CactusPCJack

+0

Ah - buona presa. Non avevo pensato a quella parte. Fammi pensare e prova a postare una soluzione più tardi dopo aver tolto alcuni dei miei incontri ... –

+0

Ok - l'unica cosa che posso pensare è di cambiare l'elenco dell'elenco tracciato per registrare anche la posizione dell'oggetto nella collezione myListOfStrings e prendi il valore minimo lì. Molto goffo, ma dovrebbe funzionare. –

3

Il LongListSelector utilizza un ScrollViewer internamente (apparentemente dal rilascio di agosto 2011). Questo fatto può essere utilizzato per ripristinare la posizione dell'elenco dopo la rimozione definitiva seguendo l'esempio fornito in http://damianblog.com/2011/01/21/wp7-scroll-pivot/ per il controller pivot.

Nel OnNavigatedFrom() ricordare il rotolo di offset:

private bool _newPageInstance = true; 
    private double _scollOffset = double.NaN; 

    protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e) 
    { 
     base.OnNavigatedFrom(e); 

     var scrollViewer = FindScrollViewer(LongList); 
     State["scrollViewer.VerticalOffset"] = scrollViewer.VerticalOffset; 
     State["PreservingPageState"] = true; 
     _newPageInstance = false; 
    } 

    private static ScrollViewer FindScrollViewer(DependencyObject parent) 
    { 
     var childCount = VisualTreeHelper.GetChildrenCount(parent); 
     for (var i = 0; i < childCount; i++) 
     { 
      var elt = VisualTreeHelper.GetChild(parent, i); 
      if (elt is ScrollViewer) return (ScrollViewer)elt; 
      var result = FindScrollViewer(elt); 
      if (result != null) return result; 
     } 
     return null; 
    } 

e ripristinarlo in OnNavigatedTo() se l'applicazione sono stati contrassegnati per la rimozione:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) 
    { 
     base.OnNavigatedTo(e); 

     if (!_newPageInstance || !State.ContainsKey("PreservingPageState")) 
     { 
      return; 
     } 

     _scollOffset = (double)State["scrollViewer.VerticalOffset"]; 
    } 

    private void LongList_Loaded(object sender, RoutedEventArgs e) 
    { 
     if (double.IsNaN(_scollOffset)) return; 

     var longListSelector = (LongListSelector)sender; 
     var scrollViewer = FindScrollViewer(longListSelector); 
     scrollViewer.ScrollToVerticalOffset(_scollOffset); 
     _scollOffset = double.NaN; 
    } 
+0

Funziona, grazie – Tim

2

Il/approccio Scollega link non funziona affatto per il ripristino della scorrere la posizione. Anche se si imposta la raccolta, non si sa se si sta scorrendo verso l'alto o verso il basso e la dimensione della raccolta varia in base alla proprietà BufferSize dello LongListSelector.

La soluzione FindScrollViewer nella risposta di kvakulo, tuttavia, funziona.

Se qualcuno ha bisogno della versione VB.Net di questo codice:

Friend Function FindScrollViewer(parent As DependencyObject) As ScrollViewer 

    Dim childCount = VisualTreeHelper.GetChildrenCount(parent) 

    For i As Int32 = 0 To childCount - 1 

     Dim elt = VisualTreeHelper.GetChild(parent, i) 

     If elt.GetType Is GetType(ScrollViewer) Then Return CType(elt, ScrollViewer) 

     Dim result = FindScrollViewer(elt) 
     If result IsNot Nothing Then Return result 

    Next 

    Return Nothing 

End Function