WPF ListBox Scroll to end automatically

后端 未结 9 765
耶瑟儿~
耶瑟儿~ 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:03

    You could try ListBox.ScrollIntoView() method, although there are some problems in some cases...

    Here is an example from Tamir Khason: Auto scroll ListBox in WPF

    0 讨论(0)
  • 2020-12-13 09:07

    The easiest way to do this:

    if (VisualTreeHelper.GetChildrenCount(listView) > 0)
    {
        Border border = (Border)VisualTreeHelper.GetChild(listView, 0);
        ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
        scrollViewer.ScrollToBottom();
    }
    

    It is always working for ListView and ListBox controls. Attach this code to the listView.Items.SourceCollection.CollectionChanged event and you have fully automatic auto-scrolling behaviour.

    0 讨论(0)
  • 2020-12-13 09:09

    listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]);

    0 讨论(0)
  • 2020-12-13 09:10

    A slightly different approach to those presented so far.

    You could use the ScrollViewer ScrollChanged event and watch for the content of the ScrollViewer getting larger.

    private void ListBox_OnLoaded(object sender, RoutedEventArgs e)
    {
        var listBox = (ListBox) sender;
    
        var scrollViewer = FindScrollViewer(listBox);
    
        if (scrollViewer != null)
        {
            scrollViewer.ScrollChanged += (o, args) =>
            {
                if (args.ExtentHeightChange > 0)
                    scrollViewer.ScrollToBottom();
            };
        }
    }
    

    This avoids some issues with the binding to the ListBox ItemsSource changing.

    The ScrollViewer can also be found without making the assumption that the ListBox is using the default control template.

    // Search for ScrollViewer, breadth-first
    private static ScrollViewer FindScrollViewer(DependencyObject root)
    {
        var queue = new Queue<DependencyObject>(new[] {root});
    
        do
        {
            var item = queue.Dequeue();
    
            if (item is ScrollViewer)
                return (ScrollViewer) item;
    
            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(item); i++)
                queue.Enqueue(VisualTreeHelper.GetChild(item, i));
        } while (queue.Count > 0);
    
        return null;
    }
    

    Then attach this to the ListBox Loaded event:

    <ListBox Loaded="ListBox_OnLoaded" />
    

    This could be easily modified to be an attached property, to make it more general purpose.

    0 讨论(0)
  • 2020-12-13 09:10

    For me, the simplest working way was this: (without Binding)

     private void WriteMessage(string message, Brush color, ListView lv)
            {
    
                Dispatcher.BeginInvoke(new Action(delegate
                {
                    ListViewItem ls = new ListViewItem
                    {
                        Foreground = color,
                        Content = message
                    };
                    lv.Items.Add(ls);
                    lv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);
                }));
            }
    

    Don't need to create classes or change the xaml, just write the messages with this method and it scroll automatically.

    Calling just

    myLv.Items.Add(ls);
    myLv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);
    

    for exemple, don't work for me.

    0 讨论(0)
  • 2020-12-13 09:11

    Try this:

    lstBox.SelectedIndex = lstBox.Items.Count -1;
    lstBox.ScrollIntoView(lstBox.SelectedItem) ;
    

    In your MainWindow, this will select and focus on last item on the list!

    0 讨论(0)
提交回复
热议问题