问题描述
在我的 C# 应用程序中,我使用自定义用户控件 (UC) 的 324 个实例的列表填充 FlowLayoutPanel (FLP),UC 包含许多文本字段和一个小 (10x10) 面板,该面板已填充带有椭圆。在填充 FLP 并从 FLP 的顶部滚动到底部后,只有前 282 个 UC 可见椭圆,而后 82 个 UC 的其余部分则不可见。但是,如果我向右滚动到 FLP 的底部,并将 324 个 UC 重新填充到 FLP 中,则所有 UC 都可以看到椭圆。
但是,更重要的是,当我调试 FLP 填充过程(循环),并检查本地选项卡中的 82 个 UC 中的任何一个,并检查绘制椭圆的面板而不做任何其他事情时,填充 FLP 后,当我向下滚动到该 UC 时,已检查的 UC 将变为可见。对我来说,这是一种奇怪的行为,我希望那里的一些专家能够对此有所了解。
我已经花了几天时间来解决这个问题,因此非常感谢各位专家的任何帮助。以下是我尝试过的方法,但都未能解决问题:
- 在 UC 中使用 PNG 填充图片框,而不是绘制椭圆。
- 在主 FLP 填充循环之后用 PNG 填充 UC 中的 PictureBox。
- 在填充后强制滚动到 FLP 的末尾,然后返回到 FLP 的顶部。
- 仅使用 324 个 UC 的子集填充 FLP,如这篇文章中的建议:Fake-scrolling containers with very many controls。这部分有效,但在滚动 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,10,10);
}
else
{
//this.picBoxStatus.Image = Properties.Resources.status_gray;
Graphics g = panelFlagged.CreateGraphics();
SolidBrush sb = new SolidBrush(Color.Gray);
g.FillEllipse(sb,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 没有:
Screenshot with 82 UCs not displaying drawing
屏幕截图显示了我在调试时检查的一个 UC,它确实显示了绘制的椭圆,而其余 82 个 UC 则没有:
Screenshot with debugged 1 of 82 UCs displaying drawing
编辑:现在问题也出现在我引入 UC 的新标签上(最初的椭圆问题由下面的第一条评论解决):
Screenshot of new label not displayed text after 282 UCs
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)