C#Winforms:如何在用鼠标拖动滚动条时更新Listbox的滚动条

C#Winforms:如何在用鼠标拖动滚动条时更新Listbox的滚动条,c#,winforms,listbox,C#,Winforms,Listbox,我有一个列表框,上面有项目的初始数量,它有垂直的滚动条 我已经实现了以下行为:如果我移动(按住鼠标左键)滚动到滚动条的末尾,那么一些新项目将添加到Listbox控件中。问题是,只有当我按下鼠标左键时,Listbox的滚动条才会更新(相对于新的Listbox项目计数)。但我需要在新项目添加到列表框后立即更新它,而无需停止向下拖动鼠标 我想要的正确行为示例:。 如您所见,如果您向下拖动滚动条,它将立即更新,并在每次加载新项目时向上跳转多个位置 所以,我的问题是:如何在不使用第三方listbox控件的

我有一个列表框,上面有项目的初始数量,它有垂直的滚动条

我已经实现了以下行为:如果我移动(按住鼠标左键)滚动到滚动条的末尾,那么一些新项目将添加到Listbox控件中。问题是,只有当我按下鼠标左键时,Listbox的滚动条才会更新(相对于新的Listbox项目计数)。但我需要在新项目添加到列表框后立即更新它,而无需停止向下拖动鼠标

我想要的正确行为示例:。 如您所见,如果您向下拖动滚动条,它将立即更新,并在每次加载新项目时向上跳转多个位置

所以,我的问题是:如何在不使用第三方listbox控件的情况下正确实现这种行为

编辑:

在我的Form1表单控件中,我通过测试滚动位置加载新项:

    public Form1()
    {
        InitializeComponent();
        ...
        var timer = new System.Windows.Forms.Timer();
        timer.Interval = 500;
        timer.Tick += TimerCheckForListItemsScrollDown;
        timer.Start();
    }

    private void TimerCheckForListItemsScrollDown(object sender, EventArgs e)
    {
        if (listBox1.Items.Count < 1)
        {
            return;
        }
        int visibleCount = listBox1.ClientSize.Height /
            ((MyListItem)(listBox1.Items[0])).ItemHeight + 1;

        if (listBox1.TopIndex == 0)
            return;


        if (listBox1.TopIndex + visibleCount > listBox1.Items.Count - 5)
        {
            InsertNextBucketOfListItems();
            //I try to invalidate and refresh control but with no positive results, while I hold left mouse button down nothing happens.
           listBox1.Invalidate();
           listBox1.Refresh();
        }

    }
public Form1()
{
初始化组件();
...
var timer=new System.Windows.Forms.timer();
计时器。间隔=500;
timer.Tick+=timerchekforListItemsScrolldown;
timer.Start();
}
私有void TimerCheckForListItemsScrollDown(对象发送方,事件参数e)
{
如果(listBox1.Items.Count<1)
{
返回;
}
int visibleCount=listBox1.ClientSize.Height/
((MyListItem)(listBox1.Items[0])。ItemHeight+1;
如果(listBox1.TopIndex==0)
返回;
如果(listBox1.TopIndex+visibleCount>listBox1.Items.Count-5)
{
InsertNextBucketOfListItems();
//我试图使控件无效并刷新控件,但没有任何积极的结果,同时按住鼠标左键,什么也没发生。
listBox1.Invalidate();
listBox1.Refresh();
}
}
编辑2:
我在下面添加了我的解决方案。

看来我找到了解决问题的方法。其主要思想是在listbox控件上生成WM_LBUTTONUP事件

我就是这样做的:

    [DllImport("user32.dll")]
    static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo);

    private void TimerCheckForListItemsScrollDown(object sender, EventArgs e)
    {
        if (listBox1.Items.Count < 1)
       {
            return;
       }
       int visibleCount = listBox1.ClientSize.Height /
            ((MyListItem)(listBox1.Items[0])).ItemHeight + 1;

       if (listBox1.TopIndex == 0)
           return;


       if (listBox1.TopIndex + visibleCount > listBox1.Items.Count - 5)
       {
           InsertNextBucketOfListItems();
           //Now is the trick
           var p = Cursor.Position;
           //0004- mouse Up
           mouse_event((uint)0x0004, (uint)p.X, (uint)p.Y, 0, UIntPtr.Zero);
       }

   }
[DllImport(“user32.dll”)]
静态外部无效鼠标事件(uint dwFlags、uint dx、uint dy、uint dwData、uintpttr dwExtraInfo);
私有void TimerCheckForListItemsScrollDown(对象发送方,事件参数e)
{
如果(listBox1.Items.Count<1)
{
返回;
}
int visibleCount=listBox1.ClientSize.Height/
((MyListItem)(listBox1.Items[0])。ItemHeight+1;
如果(listBox1.TopIndex==0)
返回;
如果(listBox1.TopIndex+visibleCount>listBox1.Items.Count-5)
{
InsertNextBucketOfListItems();
//现在是诀窍
var p=光标位置;
//0004-鼠标向上移动
鼠标事件((uint)0x0004,(uint)p.X,(uint)p.Y,0,uintpttr.Zero);
}
}

因为每次加载新项目时,滚动条都会更新。但我没有意识到如何在滚动更新后不需要释放鼠标按钮就可以继续滚动。

看来我找到了解决问题的方法。其主要思想是在listbox控件上生成WM_LBUTTONUP事件

我就是这样做的:

    [DllImport("user32.dll")]
    static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo);

    private void TimerCheckForListItemsScrollDown(object sender, EventArgs e)
    {
        if (listBox1.Items.Count < 1)
       {
            return;
       }
       int visibleCount = listBox1.ClientSize.Height /
            ((MyListItem)(listBox1.Items[0])).ItemHeight + 1;

       if (listBox1.TopIndex == 0)
           return;


       if (listBox1.TopIndex + visibleCount > listBox1.Items.Count - 5)
       {
           InsertNextBucketOfListItems();
           //Now is the trick
           var p = Cursor.Position;
           //0004- mouse Up
           mouse_event((uint)0x0004, (uint)p.X, (uint)p.Y, 0, UIntPtr.Zero);
       }

   }
[DllImport(“user32.dll”)]
静态外部无效鼠标事件(uint dwFlags、uint dx、uint dy、uint dwData、uintpttr dwExtraInfo);
私有void TimerCheckForListItemsScrollDown(对象发送方,事件参数e)
{
如果(listBox1.Items.Count<1)
{
返回;
}
int visibleCount=listBox1.ClientSize.Height/
((MyListItem)(listBox1.Items[0])。ItemHeight+1;
如果(listBox1.TopIndex==0)
返回;
如果(listBox1.TopIndex+visibleCount>listBox1.Items.Count-5)
{
InsertNextBucketOfListItems();
//现在是诀窍
var p=光标位置;
//0004-鼠标向上移动
鼠标事件((uint)0x0004,(uint)p.X,(uint)p.Y,0,uintpttr.Zero);
}
}

因为每次加载新项目时,滚动条都会更新。但我没有意识到如何在滚动更新后不需要释放鼠标按钮就可以继续滚动。

您尝试过什么吗?这个地方更多的是针对你尝试过的代码的特定问题,而不是通用方向,这更像是谷歌的目的。我从项目中添加了一些代码示例,这就是我所做的,但没有结果。现在,我只是想找到解决问题的正确方向。认识到用触摸屏操作的用户界面非常重要。一个让鼠标从桌子上掉下来或者让手指从触摸板上掉下来的程序是没有用的。你试过什么吗?这个地方更多的是针对你尝试过的代码的特定问题,而不是通用方向,这更像是谷歌的目的。我从项目中添加了一些代码示例,这就是我所做的,但没有结果。现在,我只是想找到解决问题的正确方向。认识到用触摸屏操作的用户界面非常重要。一个让鼠标从桌子上掉下来或者让手指从触摸板上掉下来的程序是没有用的。