c# - C# FlowLayoutPanel - 用户控件不显示超过一定数量的图形和标签;然而
问题描述
在我的 C# 应用程序中,我使用自定义用户控件 (UC) 的 324 个实例的列表填充 FlowLayoutPanel (FLP),UC 包含许多文本字段和一个小 (10x10) 面板,其中填充了一个椭圆. 填充 FLP 并从 FLP 的顶部滚动到底部后,只有前 282 个 UC 的椭圆可见,其余 82 个 UC 不可见。但是,如果我向右滚动到 FLP 的底部,并将 324 个 UC 重新填充到 FLP 中,所有 UC 的椭圆都可见。
然而,更重要的是,当我调试 FLP 填充过程(循环),并检查“本地”选项卡中的 82 个 UC 中的任何一个,并检查绘制椭圆的面板而不做任何其他事情时,被检查的 UC 的椭圆然后填充 FLP 后,当我向下滚动到该 UC 时变得可见。对我来说,这是一种奇怪的行为,我希望那里的一些专家能够阐明这一点。
我花了几天的时间来解决这个问题,因此非常感谢各位专家的帮助。以下是我尝试过的方法,但都未能解决问题:
- 使用 PNG 填充 UC 中的 PictureBox,而不是绘制椭圆。
- 在主 FLP 填充循环之后,使用 PNG 填充 UC 中的 PictureBox。
- 填充后强制滚动到 FLP 的末尾,然后返回到 FLP 的顶部。
- 仅使用 324 个 UC 的子集填充 FLP,如本文中建议的那样:具有非常多控件的假滚动容器。这部分有效,但在滚动 FLP 时确实会引入闪烁,因为 UC 会不断地被创建、填充和销毁。
下面是一些截图和代码片段。这是用 324 UC 填充 FLP 的代码片段:
this.Invoke(new Action(() =>
{
int i = 1;
foreach (var contact in (ContactsList.ListOfContacts))
{
ContactsListItem cliUc = new ContactsListItem()
{
Phone = contact.Phone.ToString(),
ContactName = contact.ContactName.ToString(),
Code = contact.Code.ToString(),
Flagged = contact.Flagged
};
cliUc.Colored();
cliList.Add(cliUc);
}
// REFRESH FlowLayoutPanel with list of ContactListItems from above.
this.custFlowLayout.Visible = false;
this.custFlowLayout.SuspendLayout();
// This may be tasked to a background thread so the flowlayoutpanel can appear sooner.
foreach (ContactsListItem contactsListItemOld in this.custFlowLayout.Controls)
{
contactsListItemOld.Dispose();
}
//Move to catch block, when error handling.
this.custFlowLayout.Controls.Clear();
this.custFlowLayout.Controls.AddRange(cliList.ToArray());
this.custFlowLayout.ResumeLayout(false);
this.custFlowLayout.Visible = true;
}));
这是在 UC 中绘制椭圆的代码片段:
private void panelFlagged_Paint(object sender, PaintEventArgs e)
{
if (_flagged)
{
//this.picBoxStatus.Image = Properties.Resources.status_red;
Graphics g = panelFlagged.CreateGraphics();
SolidBrush sb = new SolidBrush(Color.Red);
g.FillEllipse(sb, 0, 0, 10, 10);
}
else
{
//this.picBoxStatus.Image = Properties.Resources.status_gray;
Graphics g = panelFlagged.CreateGraphics();
SolidBrush sb = new SolidBrush(Color.Gray);
g.FillEllipse(sb, 0, 0, 10, 10);
}
return;
}
这是自定义 FLP 和 FLP 滚动事件的代码片段:
public class CustomFlowLayout : FlowLayoutPanel
{
public CustomFlowLayout()
{
// May be related to improved performance.
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
// Set this properties of this custom FlowLayoutPanel.
this.AutoScroll = false;
this.AutoSize = false;
this.WrapContents = false;
this.FlowDirection = FlowDirection.TopDown;
}
protected override void OnScroll(ScrollEventArgs se)
{
// DoEvents eliminates flickering while scrolling the panel.
Application.DoEvents();
// PerformaLayout ensures all child user controls added to this Controls are visible.
this.PerformLayout();
// INVESTIGATE following need further investigation.
base.OnScroll(se);
}
}
屏幕截图显示了成功显示绘制椭圆的 UC 的截止,然后其余 82 个 UC 没有:
屏幕截图显示了我在调试时检查的一个 UC,它确实显示了绘制的椭圆,而其余 82 个 UC 则没有:
编辑:现在问题也发生在我引入 UC 的新标签上(原来的椭圆问题由下面的第一条评论解决):
解决方案
推荐阅读
- c# - ASP.Net MVC 4 中的 SAML 2.0 实现作为 IDP
- reactjs - 更新状态后组件不会重新渲染
- swift - 如何在 ARkit 场景上方添加 UIView 固定元素
- c# - 无法从 COM 端口读取串行响应
- javascript - OneSignal 不再在 Phonegap-build 中构建
- makefile - 为什么“make”只有在隐式的情况下才会删除目标文件
- amazon-web-services - 如何从 ec2 cli 在角色之间切换?
- javascript - Chrome 不会缓存 javascript
- python - Tensorflow中某些元素的逆序
- jmeter - JMeter-将一行CSV文件读取到另一个csv文件的多行