如何滚动到 ListBox 的底部?

76

我正在使用一个 Winforms 的 ListBox 作为事件列表,希望将其填充,以便最后一个事件(底部)可见。SelectionMode 设置为 none。用户可以滚动列表,但我希望它一开始就滚动到末尾。

考虑到像 ScrollIntoView、EnsureVisible 这样的支持缺乏,我假设需要创建一个从 ListBox 继承的自定义控件;然而,我不确定接下来该怎么做。

有些提示吗?


3
常规的 listBox1.SelectedIndex = listBox1.Items.Count - 1; 对你无效吗? - M.Babcock
1
SelectionMode 未设置为 None 时,该方法有效。我需要防止在这个特定的列表中选择项目(以避免用户混淆)。 - JYelton
4个回答

99
我相信你可以通过适当设置TopIndex属性轻松实现。
例如:
int visibleItems = listBox.ClientSize.Height / listBox.ItemHeight;
listBox.TopIndex = Math.Max(listBox.Items.Count - visibleItems + 1, 0);

有点复杂,但这绝对不是你的错!感谢你提供的解决方案和示例。 - JYelton
44
如果您只是把 TopIndex 设置为最后一项,而不必担心哪一项实际上应该在顶部,似乎可以很好地工作,例如 listBox.TopIndex = listBox.Items.Count - 1; - Craig W

81

滚动到底部:

listbox.TopIndex = listbox.Items.Count - 1;

滚动到底部并选择最后一个项目:

listbox.SelectedIndex = listbox.Items.Count - 1;


2
我更喜欢这个解决方案,简单得多。谢谢! - Just Rudy
最佳解决方案。 - Vinicius Gonçalves
我的ListBox没有TopIndex属性(不知道为什么),而且设置SelectedIndex也不能滚动到所选项。 - Malcolm
@Malcolm 你在使用winforms吗? - markf78
@markf78 WPF,我的错误。这教育了我不应该忽略问题标签 >_< - Malcolm

2
这是我为WPF (.Net Framework 4.6.1)编写的代码:
Scroll.ToBottom(listBox);

使用以下实用类:
public partial class Scroll
{
    private static ScrollViewer FindViewer(DependencyObject root)
    {
        var queue = new Queue<DependencyObject>(new[] { root });

        do
        {
            var item = queue.Dequeue();
            if (item is ScrollViewer) { return (ScrollViewer)item; }
            var count = VisualTreeHelper.GetChildrenCount(item);
            for (var i = 0; i < count; i++) { queue.Enqueue(VisualTreeHelper.GetChild(item, i)); }
        } while (queue.Count > 0);

        return null;
    }

    public static void ToBottom(ListBox listBox)
    {
        var scrollViewer = FindViewer(listBox);

        if (scrollViewer != null)
        {
            scrollViewer.ScrollChanged += (o, args) =>
            {
                if (args.ExtentHeightChange > 0) { scrollViewer.ScrollToBottom(); }
            };
        }
    }
}

4
问题标记为WinForms。 - LarsTech
@LarsTech 非常好的观点,但我的回答可能会帮助一些WPF开发者,对吧? - Sean Vikoren
为什么不使用扩展方法呢? - undefined

0
如果你想要一个“当滚动到底部时停留在底部”的WinForms列表框,你可以:
int visibleItems = lb.ClientSize.Height / lb.ItemHeight;
if (lb.Items.Count > lb && lb.TopIndex > lb.Items.Count - visibleItems - 2)
  lb.TopIndex = lb.Items.Count - visibleItems + 1;

当滚动到底部时,新项目会导致它向下滚动以显示它们,但如果您向上滚动一点,那么它将停止其“跳转到底部”的行为,这样您就可以继续查看您向上滚动以查看的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接