C# Flowlayoutpanel使用鼠标滚动多个控件

C# Flowlayoutpanel使用鼠标滚动多个控件,c#,winforms,flowlayoutpanel,C#,Winforms,Flowlayoutpanel,我有一个列表,其中填充了用户控件(~300个用户控件//每个UC都有一个PictureBox和10个标签)。我在Flowlayoutpanel中显示了所有这些内容,但当我向下或向上滚动时,速度非常慢,并且有点无响应。我已经在使用一个双缓冲Flowlayoutpanel和SuspendLayout和ResumeLayout的“技巧”。我试图做的是:我用鼠标向下滚动->当前两个用户控件不再在视图中时,删除它们->从底部的列表中添加两个新的用户控件。这也应该以相反的方式工作:用鼠标向上滚动->当最后两

我有一个列表,其中填充了用户控件(~300个用户控件//每个UC都有一个PictureBox和10个标签)。我在Flowlayoutpanel中显示了所有这些内容,但当我向下或向上滚动时,速度非常慢,并且有点无响应。我已经在使用一个双缓冲Flowlayoutpanel和SuspendLayout和ResumeLayout的“技巧”。我试图做的是:我用鼠标向下滚动->当前两个用户控件不再在视图中时,删除它们->从底部的列表中添加两个新的用户控件。这也应该以相反的方式工作:用鼠标向上滚动->当最后两个不再在视图中时,移除它们->从顶部的列表中添加两个新的用户控件。

我检查并尝试了我发现的所有东西,但都不起作用。。。 我检查的一些链接:

private void FlowLayoutPanel\u MouseMove(对象发送方,MouseEventArgs e)
{
//用鼠标移动flowlayoutpanel
if(e.按钮!=鼠标按钮左)
返回;
Point pointDifference=新点(Cursor.Position.X+mouseDownPoint.X,Cursor.Position.Y-mouseDownPoint.Y);
if((mouseDownPoint.X==Cursor.Position.X)和&(mouseDownPoint.Y==Cursor.Position.Y))
返回;
Point currAutoScroll=FlowLayoutPanel.AutoScrollPosition;
FlowLayoutPanel.AutoScrollPosition=新点(Math.Abs(currAutoScroll.X)-pointDifference.X,Math.Abs(currAutoScroll.Y)-pointDifference.Y);
mouseDownPoint=光标位置;
//
Point locationOnForm=UClist[0]。FindForm()。PointToClient(
UClist[0].Parent.PointToScreen(新点(UClist[0].Location.X,UClist[0].Location.Y+300));
if(位置表格Y<190)
{
FlowLayoutPanel.SuspendLayout();
FlowLayoutPanel.Controls.Clear();
FlowLayoutPanel.Controls.AddRange(UClist.Skip(2.Take(2.ToArray());
FlowLayoutPanel.ResumeLayout();
}   
}
我该怎么办

编辑 这就是我说的
IMO,在这些链接中,你唯一应该考虑的是TAW的答案:它也是(可能)唯一一个这样做的:
FlowLayoutPanel.Controls.Clear()
不会伤害应用程序的感情(请注意,
.Controls.Clear()
不会删除控件,它只是删除父容器中的引用,因此您无法再看到它们,但这些控件及其内容仍然存在)。造成伤害的是您要显示的图像:您将加载的1000个图像,每个UC一个,将在内存中解压缩。比如说,每个非压缩图像将占用3兆字节(1MB压缩图像在内存中实际上可能会大3到10倍——可能会更大),因此您将加载3GB的图像,以及所有其他图像。因此,您必须缓存这些图像,并在FLP滚动时加载/处理这些图像。幸运的是,TaW已经编写了几乎所有您需要的内容,您只需添加缓存部分。谢谢您的回答,@Jimi!但是从TaW的回答中我不明白:float pageSize=flow layoutpanel2.ClientSize.Height/(uc1.Height+uc1.Margin.Top+uc1.Margin.Bottom);vScrollBar1.Maximum=(int)(1f*UCS.Count/(pageSize))+9;我不知道如何设置VScrollBar的最大值(以及在哪里)。我尝试在完成填充列表后将UClist.Count放入vScrollBar1.Maximum,但不起作用…您可能希望将该代码移动到一个方法,该方法将在每次修改
列表时设置新的最大值:当您向列表添加或从列表中删除一个或多个控件时,调用该方法,传递
FlowLayoutPanel
容器和滚动条控件的引用以及UC的大小(假设您的UCs都具有相同的大小,否则您可能需要将它们装箱显示)。然后,该方法可以执行该计算,并将
最大值
分配给滚动条。
 private void FlowLayoutPanel_MouseMove(object sender, MouseEventArgs e)
        {
            // move flowlayoutpanel with mouse
            if (e.Button != MouseButtons.Left)
                return;

            Point pointDifference = new Point(Cursor.Position.X + mouseDownPoint.X, Cursor.Position.Y - mouseDownPoint.Y);
            if ((mouseDownPoint.X == Cursor.Position.X) && (mouseDownPoint.Y == Cursor.Position.Y))
                return;

            Point currAutoScroll = FlowLayoutPanel.AutoScrollPosition;
            FlowLayoutPanel.AutoScrollPosition = new Point(Math.Abs(currAutoScroll.X) - pointDifference.X, Math.Abs(currAutoScroll.Y) - pointDifference.Y);
            mouseDownPoint = Cursor.Position;

            
            //
            Point locationOnForm = UClist[0].FindForm().PointToClient(
            UClist[0].Parent.PointToScreen(new Point(UClist[0].Location.X,UClist[0].Location.Y+300)));
            if (locationOnForm.Y < 190)
            {
                FlowLayoutPanel.SuspendLayout();
                FlowLayoutPanel.Controls.Clear();
                FlowLayoutPanel.Controls.AddRange(UClist.Skip(2).Take(2).ToArray());
                FlowLayoutPanel.ResumeLayout();
            }   
        }