2010-09-28 67 views

回答

3

您可以使用此,它的工作對我來說:

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

,如果您需要更高級的細節,你可以參考,這post

1

自@ pduncan的答案不包括實際的代碼,這裏是他們張貼着只有細微的修改,從我的鏈接代碼:

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

我修改它以使用MoveCurrentToLast而不是使用listBox.Items[listBox.Items.Count - 1];獲取最後一項。這樣做的原因(除了稍微清潔一點)是有邊緣的情況下,如果你有一個列表中重複項目,然後獲得listBox.Items.Count - 1,然後滾動到該項目可能不會滾動到列表的末尾(它甚至可以向相反的方向滾動你!)。它會將您滾動到該項目的第一個實例。

0

@pduncan和@MattBurland的答案都有一些問題,主要是它們未能正確取消註冊行爲。

此實現將處理程序存儲在另一個附加屬性中,以便您可以通過綁定來打開和關閉行爲。

請注意,這適用於ListView。如果您使用的是ListBox,請將ListView更改爲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; 
     } 
    } 
} 

使用方法如下:

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

我也使它成爲一個靜態類,因爲你不需要進行實例化(也不需要從DependencyObject派生)。對INotifyCollectionChanged的轉換已更改,以便錯誤顯示爲投射異常,而不是NRE。

0

對我來說,如果列表框中的每個記錄都不同,這些工作。如果它們是相同的,它就會滾動到匹配的第一個。

相關問題