2010-09-28 15 views

Antwort

3

Sie diese verwenden können, seine für mich arbeiten:

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

wenn Sie erweiterte Detail müssen Sie in diesem post

1

Da @ pduncan Antwort enthält nicht den eigentlichen Code refere kann, hier ist der Code aus dem Link sie von mir mit nur einer geringfügigen Änderung geschrieben:

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

es es geändert MoveCurrentToLast stattdessen verwenden von dem letzten Punkt mit listBox.Items[listBox.Items.Count - 1]; bekommen. Der Grund dafür (abgesehen davon, dass es sowieso ein wenig sauberer ist) ist, dass es einen Randfall gibt, in dem Sie, wenn Sie doppelte Einträge in einer Liste haben, mit listBox.Items.Count - 1 nicht zum Ende der Liste blättern (es könnte dich sogar in die entgegengesetzte Richtung scrollen!). Es würde stattdessen Sie zu der ersten Instanz dieses Elements scrollen.

0

Die Antworten von @pduncan und @MattBurland haben beide Probleme, vor allem, dass sie das Verhalten nicht ordnungsgemäß aufheben.

Diese Implementierung speichert den Handler in einer anderen angefügten Eigenschaft, sodass Sie das Verhalten möglicherweise durch eine Bindung ein- und ausschalten können.

Beachten Sie, dass dies für ListView gilt. Wenn Sie ListBox verwenden, ändern Sie das Vorkommen ListView in 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; 
     } 
    } 
} 

es wie folgt verwendet:

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

Ich habe es auch eine statische Klasse, wie Sie es nicht instanziiert müssen (auch nicht von DependencyObject ableiten müssen). Die Umwandlung in INotifyCollectionChanged wurde geändert, so dass Fehler als Ausnahmen auftreten, nicht als NREs.

0

Für mich funktionieren diese, wenn jeder Datensatz in der Listbox unterschiedlich ist. Wenn sie gleich sind, scrollt sie einfach zu der ersten Übereinstimmung.

Verwandte Themen