gpt4 book ai didi

c# - 带有很多控件的假滚动容器

转载 作者:行者123 更新时间:2023-11-30 21:45:50 25 4
gpt4 key购买 nike

我正在尝试优化 FlowLayoutPanel 的填充和滚动,但我之前遇到过类似控件的问题,如果它们内部的控件太多,容器填充和准备就绪需要很长时间使用(滚动条变得越来越短,您可能对此很熟悉)。

我读到过,您可以只使用容器矩形可见边界内的控件池,并通过用相应的内容重新填充它们来模拟滚动,就好像它们没有这种优化一样。所以你像往常一样滚动,但人口不会花费那么长的时间。但对于一般情况,我该如何实现呢?

我正在使用自定义控件来填充 FlowLayoutPanel 容器,因此我正在寻找一种足够通用的解决方案,既可以应用于我的控件,也可以应用于标准 .Net 控件。

最佳答案

显示和滚动性能尝试虚拟分页的充分理由,尽管可以通过替换 Controls.Add 来克服它们用Controls.AddRange调用和双缓冲容器..

..但是另一个:任何 Winforms 控件的显示尺寸都限制为 32k 像素。即使您将其放大,也不会显示超出此限制的任何内容。

以下是实现虚拟分页时要做的事情的快速列表:

  • 使用双缓冲 FlowLayoutPanel子类化以简化布局并使其无闪烁。
  • 关闭 AutoSizeAutoScroll
  • 添加 VScrollBar在 FLP 的右侧并保持其 Height和FLP的一样
  • 计算 Height (加上 Margins )你的 UserControl .我假设您将控件封装在 UC 中,以使事情变得更简单。
  • 计算分页数
  • 创建 List<yourUserControlClass> theUCs
  • 现在创建您的 UC,但仅将它们添加到列表 theUCs
  • 编码 scrollTo(int ucIndex)函数,该函数清除 FLP 的控件并从列表中添加正确的范围
  • 代码 KeyPreview让 FLP 允许使用键盘滚动。

VScrollBar 设置正确的值的属性,即 Minimum, Maximum, Value, SmallChange, LargeChange有点棘手,每当 FLP 调整大小或元素被添加到列表或从列表中删除时,都必须设置页面大小。

在我的测试中,设置和滚动结果是即时的。从顶部只能看到完整 UC,这对我来说很好。我在 Panel 中添加了带有位图的 1000 UC , 一个 Label和一个 CheckedListBox .

以下是我如何计算 Maximum 的设置:

float pageSize =  flowLayoutPanel2.ClientSize.Height / 
(uc1.Height + uc1.Margin.Top + uc1.Margin.Bottom);
vScrollBar1.Maximum = (int)( 1f * theUCs.Count / (pageSize)) + 9;

额外的9ScrollBar 的古怪偏移的解决方法的理论与实际Maximum值(value)观。

ValueChanged我写的事件:

private void vScrollBar1_ValueChanged(object sender, EventArgs e)
{
int pageSize = flowLayoutPanel1.ClientSize.Height / theUCs.First().Height;
int v = Math.Min(theUCs.Count, vScrollBar1.Value);

flowLayoutPanel1.SuspendLayout();
flowLayoutPanel1.Controls.Clear();
flowLayoutPanel1.Controls.AddRange(theUCs.Skip( (v- 1) * pageSize)
.Take(pageSize + 1).ToArray());
flowLayoutPanel1.ResumeLayout();
}

滚动到某个项目:

void scrollTo(int item)
{
int pageSize = flowLayoutPanel1.ClientSize.Height / theUCs.First().Height;
int p = item / pageSize + 1;
vScrollBar1.Value = p;
}

为了更流畅的滚动使用 DoubleBuffered子类:

class DrawFLP : FlowLayoutPanel
{
public DrawFLP() { DoubleBuffered = true; }
}

这可能有点粗糙,但我希望它能让您走上正轨。

enter image description here

关于c# - 带有很多控件的假滚动容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39808934/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com