为什么这个 FlowLayoutPanels 列表是以奇怪的模式绘制的

本文关键字:模式 绘制 FlowLayoutPanels 列表 为什么 | 更新日期: 2023-09-27 18:19:15

我有一个程序,可以将小FlowLayoutPanels添加到较大的Panel,或者至少是这个意图。每个FlowLayoutPanel都包含几个其他的简单Controls,并存储在一个名为skillPanel的List<FlowLayoutPanel>中。

当单击按钮向Panel添加新FlowLayoutPanel时,会生成一个并存储在技能面板中。 然后将 skillPanels 深度复制到一个支架(命名为 err...holder(,然后完全丢弃以摆脱UI中可见的FlowLayoutPanels - 每个FlowLayoutPanel都有其子项Dispose-d,然后是Dispose本身。为了更好地衡量,列表是 .Clear((-ed.

清理石板后,持有人被深度复制回skillPanel,然后对其进行迭代并将其成员添加到更大的Panel中,手动定位每个,因为我不信任布局管理器,因为我可以扔他们。遗憾的是,这种级别的迂回性需要将来添加的每个 FlowLayoutPanel 删除方法。通过逐步执行代码并提供MessageBoxes,我确信每个代码都被添加到更大的Panel中。

问题是:尽管.Add Panel,但只有其中一些人出现了。我怀疑.Dispose方法是以某种方式受到指责,但我无法解释如何或为什么。

为了我自己的理智,以及一定程度的清晰度,这是FlowLayoutPanel在点击之后可见的模式:

第1个添加: 1

第 2 个添加:2(即 1 个已消失(

第三添加:2、3

第四添加: 2, 4

第五添加: 2, 4, 5

第六添加: 4, 6

第七添加: 4, 6, 7

第8添加: 6, 8

第9地址: 6, 8, 9

看到图案形成了吗?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        List<FlowLayoutPanel> skillPanels = new List<FlowLayoutPanel>();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            Panel pnlMacroSkillsPanel = new Panel();
            pnlMacroSkillsPanel.Height = this.Height;
            pnlMacroSkillsPanel.Width = this.Width;
            Button btnAddSkill = new Button();
            btnAddSkill.Click += new EventHandler(btnAddSkill_Click);
            pnlMacroSkillsPanel.Controls.Add(btnAddSkill);
            this.Controls.Add(pnlMacroSkillsPanel);            
        }
        void reDrawSkillPanels(Panel pan)
        {
            FlowLayoutPanel plato = new FlowLayoutPanel();
            List<FlowLayoutPanel> holder = new List<FlowLayoutPanel>(skillPanels.Count);
            foreach (FlowLayoutPanel f in skillPanels)
            {
                holder.Add(f);
            }
            try
            {
                foreach (object f in pan.Controls)
                {
                    if (f is FlowLayoutPanel)
                    {
                        plato = (FlowLayoutPanel)f;
                        MessageBox.Show("Disposing of FlowLayoutPanel");
                        foreach (Control c in plato.Controls)
                        {
                            c.Dispose();
                        }
                        ((FlowLayoutPanel)f).Dispose();
                    }
                }
                skillPanels.Clear();
            }
            catch (Exception e)
            {
                //
            }
            foreach (FlowLayoutPanel f in holder)
            {
                skillPanels.Add(f);
            }
            holder.Clear();
            int initialYoffset = 40;
            for (int count = 0; count < skillPanels.Count; count++)
            {
                plato = new FlowLayoutPanel();
                plato = skillPanels[count];
                plato.Top = initialYoffset + ((plato.Height + 4) * count);
                plato.Left = 4;
                //MessageBox.Show("Adding skillPanels member at: 4, " + (initialYoffset + ((skillPanels[count].Height + 4) * count)) + "!");
                //MessageBox.Show("ToString:" + skillPanels[count].ToString() + ", Width: " + skillPanels[count].Width);
                pan.Controls.Add(plato);
            }
            //MessageBox.Show("skillPanels.Count = " + skillPanels.Count);
        }
        void btnAddSkill_Click(object sender, EventArgs e)
        {
            Button plato = (Button)sender;
            FlowLayoutPanel pnlNewSkill = new FlowLayoutPanel
            pnlNewSkill.FlowDirection = FlowDirection.LeftToRight;
            pnlNewSkill.Height = 30;
            pnlNewSkill.Width = 350;
            Random r = new Random();
            Color randomColor = Color.FromArgb(r.Next(255), r.Next(255), r.Next(255));
            pnlNewSkill.BackColor = randomColor;
            /*
             * Code creating and adding Controls to pnlNewPanel would go here
             */
            skillPanels.Add(pnlNewSkill);
            reDrawSkillPanels(((Panel)(plato.Parent)));
        }
    }
}

为什么这个 FlowLayoutPanels 列表是以奇怪的模式绘制的

当您将

面板添加到列表中时skillPanels该面板将保留在那里,即使您稍后使用 pan.Controls.Add 添加它也是如此。因此,当第二次单击发生时,您Dispose它,然后再次添加它以及新面板。第三次单击后,您Dispose第二个,现在您的列表包含 2 个已处理的面板和一个新面板。所有这些都是你添加到pan,等等。

所以基本上,你在skillPanels列表中堆积了已处理的面板,然后你不断将它们重新添加到for循环中的pan.Controls,尽管它们已经被处置了。

不确定您需要列表做什么 - 您可以直接在btnAddSkill_Click中添加新面板。另一种可能性是从列表中删除它们,无论是在将其添加到pan.Controls之后还是在处置它们时。