C# Winforms:具有数千个用户控件的可滚动FlowLayoutPanel-如何防止内存泄漏并以正确的方式处理对象?

C# Winforms:具有数千个用户控件的可滚动FlowLayoutPanel-如何防止内存泄漏并以正确的方式处理对象?,c#,winforms,memory-leaks,user-controls,flowlayoutpanel,C#,Winforms,Memory Leaks,User Controls,Flowlayoutpanel,我对windows窗体编程比较陌生。我正在开发一个windows窗体应用程序,它要求用户在窗体中滚动(我在窗体中使用了一个带有AutoScroll=True的FlowLayoutPanel)。 该面板的源包含一个用户控件,该控件根据记录数循环 例如,如果DB中有10条记录,则在加载表单时,将创建10个用户控件并将其添加到面板中,用户将能够滚动浏览这10项。(请参见描述此场景的示例图像) 问题: 当有更多记录(比如1000条)时,就会出现问题,因为没有释放usercontrol对象,并且超过了句

我对windows窗体编程比较陌生。我正在开发一个windows窗体应用程序,它要求用户在窗体中滚动(我在窗体中使用了一个带有AutoScroll=True的FlowLayoutPanel)。 该面板的源包含一个用户控件,该控件根据记录数循环

例如,如果DB中有10条记录,则在加载表单时,将创建10个用户控件并将其添加到面板中,用户将能够滚动浏览这10项。(请参见描述此场景的示例图像)

问题:

当有更多记录(比如1000条)时,就会出现问题,因为没有释放usercontrol对象,并且超过了句柄限制,所以应用程序崩溃(并显示一条消息:创建窗口句柄时出错)。我知道这是内存泄漏或设计不好的问题

但我无法在这里找到可靠的解决方案,我已经考虑了以下选项(克服问题),但不确定如何继续:

  • 仅加载用户屏幕上可见的UserControls,并动态处理其他UserControls(当用户滚动或按下向上/向下按钮时)
  • 是否可以在面板中将usercontrols呈现为图像,并且在悬停或单击任何部分时,可以重新初始化用户控件并触发加载(这样,实际的用户控件对象将不在内存中)

  • 您能建议一个合适的解决方案/在这个需求的上下文中处理UserControl对象的正确方法吗

    我建议使用
    DataGridView

    我将能保存1000张唱片

    你有两种选择

    • 坚持其直网格状布局或
    • 选择了混合布局
    我指的是一个解决方案,它将当前记录以外的所有记录显示为网格中的一行;当前行可以通过
    UserControl
    的一个实例进行放大和覆盖,该实例在所选行发生更改时从基础行的数据中加载

    有关此技术的示例,请参见;在这里,我展示了如何用更大的区域替换当前行,这与手风琴控件的工作方式非常相似

    DGV中的行实际上只是一个
    位图
    ,因此滚动成本低;使用DGV的正常方法是依靠其将一个单元格与正确类型的编辑控件叠加的能力

    “手风琴技巧”将其扩展到覆盖整行的任意
    UserControl


    请注意,其他行占用的空间要小得多,我认为这是一个额外的好处。

    您考虑过使用某种形式的分页吗?例如,您的LayoutPanel将始终显示10个用户控件(无滚动条),然后添加页码供用户浏览您的记录,每次10个?当您希望避免加载大量数据并使UI变得混乱时,这是一种常用的方法??UserControl的可伸缩性不是很好,必须在困难学校学习。操作系统对您可以创建的控件数量设置了硬限制,即UserControl加上其所有子控件,不能超过10000个。使用可以显示多行信息的控件,如ListView和DataGridView。看看谷歌是否能提供数万个结果。@是的,我确实考虑过分页,它会解决这个问题,但是这对用户来说不是很令人满意(因为他们不想用分页来导航,而是想滚动)。因此,我试图找出是否可以做任何其他事情。您不使用DataGridView的原因是什么,它是为如此多的记录构建的???@TaW:设计最初是基于用户控制的,有没有一种方法可以将所有这些用户控制操作到DataGridView(而不是面板)中为了避免这个问题?谢谢你的回复。您已经提到DGV中的行是位图。那么,是否有一种方法可以在DGV中将“所有”用户控件作为单独的行进行操作(而不是显示网格并一次只覆盖一行?)。添加所有这些UCs毫无意义,这正是您在FLP中尝试的方法。我提到的位图不适用于每一行;它被创建为一个单独的(内部)位图,显示方式与图像一样。成千上万的控件在Winforms中工作得很好。不过,WPF可以轻松处理这一问题。。您可以继续绘制任意布局的位图,并对面板或picturebox进行编码以显示该位图,并映射所有鼠标和键盘动作以做出反应并生成新的更新版本。但这将是相当多的工作,取决于互动的程度。不推荐