如何通过编程实现ListView的滚动

9
我在WinForms应用程序中使用了一个listview控件。
在单击单独的按钮时,我会更改几个listview项的背景颜色,并重新加载整个网格,因为数据库中有某些更改,因此需要在每次单击按钮时重新加载。
现在的问题是,一旦网格重新加载,最后添加的项目就会滚动,所以需要滚动所有项目并查找,这使最终用户感到困难。
有没有办法自动滚动listview中最后添加或更新的项目(我的意思是,通过编程方式,这可以直接显示给用户,而无需手动滚动)?

你能否简单地将项目排序,使最后添加的项目位于列表框的顶部?这样就不需要滚动到底部才能看到它们。这似乎是最简单的方法。 - BenjaminPaul
如果添加的项始终是ListView中的最后一项,您可以使用此答案:https://dev59.com/OHI-5IYBdhLWcg3wF0Yc - Apostrofix
如果不是最后一个(例如更新的项目),那么您可以在按钮单击时存储该项的索引并滚动到它,方法是执行 listView1.Items[itemIndex].EnsureVisible(); - Apostrofix
4个回答

10

listView1.EnsureVisible(X);

其中X是项的索引。
此代码片段可用于自动滚动ListView到listView中的特定索引。
考虑以下代码:使用此代码,您可以在单击按钮时自动滚动到索引8
 private void button2_Click(object sender, EventArgs e)
 {
     listView1.EnsureVisible(8);
 }

它看起来很简单,但似乎无法可靠地工作。 - Neil Dunlop
2
@NeilDunlop,你可能在表单创建时尝试过它,但它肯定不起作用。但是,如果您将此实现移动到加载事件或其他不属于初始化的代码部分,它应该可以正常工作。 - ehh
@ehh 谢谢。我会检查一下去年我做的事情,但是如果我正确理解了你的建议,我不认为它能解决我遇到的问题。我不是在动态创建表单。所有我的表单都是使用 VSTO 表单设计器创建的,然后使用... - Neil Dunlop

1
可以直接发送消息。
public partial class Form1 : Form
{
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

    public Form1()
    {
        InitializeComponent();

        c_scroll.ScrollSlide += C_scroll_ScrollSlide;

    }

    private void C_vScrollBar_Scroll(object sender, ScrollEventArgs e)
    {
        const int LVM_SCROLL = (0x1000 + 20);
        SendMessage(c_listView_show.Handle, LVM_SCROLL, 0, e.NewValue - e.OldValue);

    }


}

1
尽管@user3711357的答案是正确的,但我花了太多时间试图理解为什么它对我不起作用。 我发现在表单的构造函数中尝试调用EnsureVisible是行不通的。
public class MyForm
{
    public MyForm()
    {
        InitializeComponent();
        listView1.EnsureVisible(8);  // will not work !!!
    }

    private void MyForm_Load(object sender, EventArgs e)
    {
        listView1.EnsureVisible(8);  // Works fine
    }
}

0
在刷新列表之前,将当前聚焦或选定的项目(取决于您的交互代码如何工作)存储到一个变量中,然后可以在之后恢复选定的项目。例如:
Dim selectedObjectName = listview.SelectedItems(0).Name
...
' refresh your list
...
Dim vItem as ListViewItem
If listview.SelectedItem.ContainsKey(selectedObjectName) Then 
    vItem = listview.Items(selectedObjectName)
Else
    vItem = listview.Items(0)
End If
vItem.Selected = True
vItem.Focus

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