2010-12-16 13 views
6

Estoy tratando de lograr un efecto donde más artículos se anexen a la lista cuando el usuario se desplaza hacia abajo hasta el último elemento. No he encontrado una manera de determinar si el usuario se desplazó al final de la lista. No veo un evento en ListBox que se dispare cuando el usuario llega al final de la lista. Algo que me diga cuándo se ha desplazado un elemento a la vista sería genial, pero hasta donde sé, no hay nada como eso.WP7 Auto Grow ListBox al llegar al último artículo

¿Esto es posible incluso en WP7?

Editar: Otra forma de decir que esto es, ¿podemos detectar cuándo una lista ha "rebotado"?

Respuesta

-1
+0

Este no es el efecto que está siendo buscado por desgracia. –

5

No es súper fácil ponerse en marcha ya que hay muchas partes móviles, pero esto es lo que puede hacer, suponiendo que quiere una lista corta que carga más de sus datos a medida que se desplaza hacia abajo, similar a una gran cantidad de aplicaciones de Twitter, etc.

  • Escribe tu propia subclase de ObservableCollection que sólo ofrece algunos artículos (como 20), manteniendo el resto retenido hasta que se solicite
  • Hook hasta el espectador de desplazamiento (en el interior el cuadro de lista o contenedor) y sus eventos modificados de estado visual, puede obtener los cambios NotScrolling y Scrolling; para un ejemplo see this code by ptorr
  • Al desplazarse paradas, utilizar viewer scroll extensions code para ver donde se extienden las cosas (en la parte inferior o no) o sólo las propiedades de visualización de desplazamiento primas para ver si se extiende a la parte inferior
  • Si es así, desencadenar su colección observable para lanzar otro conjunto de artículos.

Lo siento, todavía no tengo una muestra completa lista para blog. ¡Buena suerte!

5

Acabo de implementar esto para Overflow7.

El enfoque que tomamos fue similar a http://blog.slimcode.com/2010/09/11/detect-when-a-listbox-scrolls-to-its-end-wp7/

Sin embargo, en lugar de utilizar un estilo que hice el gancho en código.

deriva básicamente mi UserControl padres de:

public class BaseExtendedListUserControl : UserControl 
{ 
    DependencyProperty ListVerticalOffsetProperty = DependencyProperty.Register(
     "ListVerticalOffset", 
     typeof(double), 
     typeof(BaseExtendedListUserControl), 
     new PropertyMetadata(new PropertyChangedCallback(OnListVerticalOffsetChanged))); 

    private ScrollViewer _listScrollViewer; 

    protected void EnsureBoundToScrollViewer() 
    { 
     if (_listScrollViewer != null) 
      return; 

     var elements = VisualTreeHelper.FindElementsInHostCoordinates(new Rect(0,0,this.Width, this.Height), this); 

     _listScrollViewer = elements.Where(x => x is ScrollViewer).FirstOrDefault() as ScrollViewer; 

     if (_listScrollViewer == null) 
      return; 

     Binding binding = new Binding(); 
     binding.Source = _listScrollViewer; 
     binding.Path = new PropertyPath("VerticalOffset"); 
     binding.Mode = BindingMode.OneWay; 
     this.SetBinding(ListVerticalOffsetProperty, binding); 
    } 

    public double ListVerticalOffset 
    { 
     get { return (double)this.GetValue(ListVerticalOffsetProperty); } 
     set { this.SetValue(ListVerticalOffsetProperty, value); } 
    } 

    private static void OnListVerticalOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     BaseExtendedListUserControl control = obj as BaseExtendedListUserControl; 
     control.OnListVerticalOffsetChanged(); 
    } 

    private void OnListVerticalOffsetChanged() 
    { 
     OnListVerticalOffsetChanged(_listScrollViewer); 

    } 

    protected virtual void OnListVerticalOffsetChanged(ScrollViewer s) 
    { 
     // do nothing 
    } 
} 

esto, entonces significa que en el propio control de usuario tan sólo pudiera utilizar:

 protected override void OnListVerticalOffsetChanged(ScrollViewer viewer) 
    { 
     // Trigger when at the end of the viewport 
     if (viewer.VerticalOffset >= viewer.ScrollableHeight) 
     { 
      if (MoreClick != null) 
      { 
       MoreClick(this, new RoutedEventArgs()); 
      } 
     } 
    } 

    private void ListBox1_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) 
    { 
     EnsureBoundToScrollViewer(); 
    } 

Lo "hacky" aquí era que tenía a use ListBox1_ManipulationCompleted y VisualTreeHelper para encontrar mi ScrollViewer - Estoy seguro de que hay mejores formas ...

+0

+1 - parece ser la mejor opción desagradable. – McGarnagle

7

Daniel Vaughan ha publicado un ejemplo de cómo detectar esto en http://danielvaughan.orpius.com/post/Scroll-Based-Data-Loading-in-Windows-Phone-7.aspx

+0

Desafortunadamente, esto provoca pérdidas de memoria como se describe en http://support.microsoft.com/kb/938416. El resultado es que GC no lanzará una página que use esta técnica. –

+0

@Agent_L - ¿Sabes si esto se resolvió para Windows Phone 8? No puedo decir que lo entiendo, pero acabo de implementar la nueva versión de Daniel Vaughans en su W8 desatada, y quiero asegurarme de que no me estoy perdiendo algo aquí. – Jimmyt1988

+0

@ Jimmyt1988 No tengo ni idea, uso otra solución. En mi humilde opinión, todos los conceptos basados ​​en llegar al final de desplazamiento exacto son defectuosos. El usuario puede desplazarse * casi * hasta el final y, por lo tanto, nunca disparar la acción de carga. Estoy usando un elemento extra agregado al final de la lista que muestra "cargando" todo el tiempo, y este elemento entra en la vista ('get' es invocado por la interfaz de usuario en la lista virtualizada) desencadena la carga de más datos. Tiene 2 beneficios: el usuario es informado inmediatamente de que la lista se está cargando, y la acción de carga realmente ocurre algún tiempo antes de que aparezca. Por lo tanto, con una conexión rápida, el usuario nunca podrá ver los elementos que saltan. –