首页 > 解决方案 > 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 时变得可见。对我来说,这是一种奇怪的行为,我希望那里的一些专家能够阐明这一点。

我花了几天的时间来解决这个问题,因此非常感谢各位专家的帮助。以下是我尝试过的方法,但都未能解决问题:

下面是一些截图和代码片段。这是用 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 没有:

不显示绘图的 82 UC 的屏幕截图

屏幕截图显示了我在调试时检查的一个 UC,它确实显示了绘制的椭圆,而其余 82 个 UC 则没有:

已调试 82 个 UC 中的 1 个显示绘图的屏幕截图

编辑:现在问题也发生在我引入 UC 的新标签上(原来的椭圆问题由下面的第一条评论解决):

282 UCs 后新标签未显示文本的屏幕截图

标签: c#winformsgraphicsuser-controlsflowlayoutpanel

解决方案


推荐阅读