2010-09-28 14 views

Respuesta

3

se puede utilizar este, su trabajo para mí:

this.myListView.ScrollIntoView (myListView.Items [myListView.Items.Count-1]);

si necesita detalle más avanzado puede refere a este post

1

Dado que la respuesta de @ pduncan no incluye el código real, aquí está el código desde el enlace que se publican con sólo una pequeña modificación de mí:

public class ListBoxExtenders : DependencyObject 
{ 
    public static readonly DependencyProperty AutoScrollToEndProperty = DependencyProperty.RegisterAttached("AutoScrollToEnd", typeof(bool), typeof(ListBoxExtenders), new UIPropertyMetadata(default(bool), OnAutoScrollToEndChanged)); 

    /// <summary> 
    /// Returns the value of the AutoScrollToEndProperty 
    /// </summary> 
    /// <param name="obj">The dependency-object whichs value should be returned</param> 
    /// <returns>The value of the given property</returns> 
    public static bool GetAutoScrollToEnd(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(AutoScrollToEndProperty); 
    } 

    /// <summary> 
    /// Sets the value of the AutoScrollToEndProperty 
    /// </summary> 
    /// <param name="obj">The dependency-object whichs value should be set</param> 
    /// <param name="value">The value which should be assigned to the AutoScrollToEndProperty</param> 
    public static void SetAutoScrollToEnd(DependencyObject obj, bool value) 
    { 
     obj.SetValue(AutoScrollToEndProperty, value); 
    } 

    /// <summary> 
    /// This method will be called when the AutoScrollToEnd 
    /// property was changed 
    /// </summary> 
    /// <param name="s">The sender (the ListBox)</param> 
    /// <param name="e">Some additional information</param> 
    public static void OnAutoScrollToEndChanged(DependencyObject s, DependencyPropertyChangedEventArgs e) 
    { 
     var listBox = s as ListBox; 
     if (listBox != null) 
     { 
      var listBoxItems = listBox.Items; 
      var data = listBoxItems.SourceCollection as INotifyCollectionChanged; 

      var scrollToEndHandler = new System.Collections.Specialized.NotifyCollectionChangedEventHandler(
       (s1, e1) => 
       { 
        if (listBox.Items.Count > 0) 
        { 
         listBoxItems.MoveCurrentToLast(); 
         listBox.ScrollIntoView(listBoxItems.CurrentItem); 
        } 
       }); 

      if ((bool)e.NewValue) 
       data.CollectionChanged += scrollToEndHandler; 
      else 
       data.CollectionChanged -= scrollToEndHandler; 
     } 
    } 
} 

he modificado para utilizar MoveCurrentToLast en lugar de obtener el último elemento con listBox.Items[listBox.Items.Count - 1];. La razón de esto (aparte de ser un poco más limpio) es que hay un caso límite en el que si tienes elementos duplicados en una lista, entonces obtener listBox.Items.Count - 1 y luego desplazarte a ese elemento podría no deslizarte hasta el final de la lista (incluso podría desplazarte en la dirección opuesta!). En su lugar, lo desplazará a la primera instancia de ese elemento.

0

Las respuestas de @pduncan y @MattBurland ambos tienen algunos problemas, principalmente que no logran eliminar el registro de la conducta adecuada.

Esta aplicación almacena el controlador en otra propiedad adjunta para que pueda cambiar el comportamiento dentro y fuera, quizás a través de un enlace.

Tenga en cuenta que esto se aplica a ListView. Si está utilizando ListBox, cambie las ocurrencias de ListView a ListBox.

public static class ListViewExtensions 
{ 
    public static readonly DependencyProperty AutoScrollToEndProperty = DependencyProperty.RegisterAttached("AutoScrollToEnd", typeof(bool), typeof(ListViewExtensions), new UIPropertyMetadata(OnAutoScrollToEndChanged)); 
    private static readonly DependencyProperty AutoScrollToEndHandlerProperty = DependencyProperty.RegisterAttached("AutoScrollToEndHandler", typeof(NotifyCollectionChangedEventHandler), typeof(ListViewExtensions)); 

    public static bool GetAutoScrollToEnd(DependencyObject obj) => (bool)obj.GetValue(AutoScrollToEndProperty); 
    public static void SetAutoScrollToEnd(DependencyObject obj, bool value) => obj.SetValue(AutoScrollToEndProperty, value); 

    private static void OnAutoScrollToEndChanged(DependencyObject s, DependencyPropertyChangedEventArgs e) 
    { 
     var listView = s as ListView; 

     if (listView == null) 
      return; 

     var source = (INotifyCollectionChanged)listView.Items.SourceCollection; 

     if ((bool)e.NewValue) 
     { 
      NotifyCollectionChangedEventHandler scrollToEndHandler = delegate 
      { 
       if (listView.Items.Count <= 0) 
        return; 
       listView.Items.MoveCurrentToLast(); 
       listView.ScrollIntoView(listView.Items.CurrentItem); 
      }; 

      source.CollectionChanged += scrollToEndHandler; 

      listView.SetValue(AutoScrollToEndHandlerProperty, scrollToEndHandler); 
     } 
     else 
     { 
      var handler = (NotifyCollectionChangedEventHandler)listView.GetValue(AutoScrollToEndHandlerProperty); 

      source.CollectionChanged -= handler; 
     } 
    } 
} 

utilizar de esta manera:

<ListView local:ListViewExtensions.AutoScrollToEnd="{Binding Path=AutoScroll}"> 

También hice un una clase estática, ya que no es necesario crear una instancia (ni necesita derivar de DependencyObject). El lanzamiento al INotifyCollectionChanged se modificó para que los errores surgen como excepciones de lanzamiento, no NRE.

0

Para mí, éstos funcionan si cada registro en el cuadro de lista es diferente. Si son iguales, simplemente se desplaza al primero que coincida.

Cuestiones relacionadas