WPF ListBox Scroll to end automatically

后端 未结 9 766
耶瑟儿~
耶瑟儿~ 2020-12-13 08:25

In my application, I have a ListBox with items. The application is written in WPF.

How can I scroll automatically to the last added item? I want the

相关标签:
9条回答
  • 2020-12-13 09:11

    The most easiest way to achieve autoscrolling is to hook on the CollectionChanged event. Just add that functionality to a custom class which derives from ListBox control:

    using System.Collections.Specialized;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace YourProgram.CustomControls
    {
      public class AutoScrollListBox : ListBox
      {
          public AutoScrollListBox()
          {
              if (Items != null)
              {
                  // Hook to the CollectionChanged event of your ObservableCollection
                  ((INotifyCollectionChanged)Items).CollectionChanged += CollectionChange;
              }
          }
    
          // Is called whenever the item collection changes
          private void CollectionChange(object sender, NotifyCollectionChangedEventArgs e)
          {
              if (Items.Count > 0)
              {
                  // Get the ScrollViewer object from the ListBox control
                  Border border = (Border)VisualTreeHelper.GetChild(this, 0);
                  ScrollViewer SV = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
    
                  // Scroll to bottom
                  SV.ScrollToBottom();
              }
          }
      }
    }
    

    Add the namespace of the custom control to your WPF window and use the custom ListBox control:

    <Window x:Class="MainWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:YourProgram"
             xmlns:cc="clr-namespace:YourProgram.CustomControls"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    
        <cc:AutoScrollListBox ItemsSource="{Binding YourObservableCollection}"/>
    
    </Window>
    
    0 讨论(0)
  • 2020-12-13 09:17

    The best solution is to use the ItemCollection object inside the ListBox control this collection was specially designed to content viewers. It has a predefined method to select the last item and keep a cursor position reference....

    myListBox.Items.MoveCurrentToLast();
    myListBox.ScrollIntoView(myListBox.Items.CurrentItem);
    
    0 讨论(0)
  • 2020-12-13 09:26

    Keep in mind that listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]); works only if you have no duplicate items. If you have items with the same contents it scrolls down to the first find.

    Here is the solution I found:

    ListBoxAutomationPeer svAutomation = (ListBoxAutomationPeer)ScrollViewerAutomationPeer.CreatePeerForElement(myListBox);
    
    IScrollProvider scrollInterface = (IScrollProvider)svAutomation.GetPattern(PatternInterface.Scroll);
    System.Windows.Automation.ScrollAmount scrollVertical = System.Windows.Automation.ScrollAmount.LargeIncrement;
    System.Windows.Automation.ScrollAmount scrollHorizontal = System.Windows.Automation.ScrollAmount.NoAmount;
    //If the vertical scroller is not available, the operation cannot be performed, which will raise an exception. 
    if ( scrollInterface.VerticallyScrollable )
        scrollInterface.Scroll(scrollHorizontal, scrollVertical);
    
    0 讨论(0)
提交回复
热议问题