Почему этот список FlowLayoutPanels рисуется странным образом?

1

У меня есть программа, которая добавляет небольшие FlowLayoutPanels к большей Panel или, по крайней мере, к намерению. Каждая FlowLayoutPanel содержит несколько других простых Controls и хранится в List<FlowLayoutPanel> именем skillPanels.

Когда кнопка нажата, чтобы добавить новую Panel FlowLayoutPanel в Panel, она создается и сохраняется в классах навыков. skillPanels затем глубоко скопированы в держатель (named, err... holder), а затем полностью уничтожены, чтобы избавиться от FlowLayoutPanels видимых в UI-, у каждого FlowLayoutPanel есть свои дочерние объекты Dispose-d, а затем Disposed. Для хорошей меры, List is then.Clear() -ed.

После очистки сланца, держатель полностью скопирован обратно в skillPanels, который затем повторяется над ним и добавляет его членов в большую Panel, позиционируя каждый вручную, поскольку я не доверяю менеджерам макетов, насколько могу их бросить. Этот уровень обходности, к сожалению, необходим для метода удаления каждого потока FlowLayoutPanel, который будет добавлен в будущем. Поступая через код и предоставляя MessageBoxes, я точно знаю, что каждый добавлен в большую Panel.

Но вот кикер: несмотря на .Add -ing на Panel, только некоторые из них появляются. Я подозреваю, что метод .Dispose виноват, но я не могу объяснить, как и почему.

Для моего собственного здравомыслия, а также степени ясности, это шаблон, из которого видно FlowLayoutPanel после которого клики:

1-е место: 1

2-я добавка: 2 (т.е. 1 исчез)

3-е место: 2, 3

4-е место: 2, 4

5-е место: 2, 4, 5

6-е добавление: 4, 6

7-й дополнительный: 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)));
        }
    }
}
  • 0
    На первый взгляд я не вижу избавления от того, что содержит каждая FlowLayoutPanel . Это не будет автоматом. Вы могли бы накапливать ручки.
  • 0
    Попробовал добавить его в мою нередактированную версию, безрезультатно. Добавлю это к вышесказанному, спасибо.
Теги:
winforms
c#-4.0
flowlayoutpanel

1 ответ

1
Лучший ответ

Когда вы добавляете панель в свой список skillPanels она остается там, даже когда вы добавляете ее с pan.Controls.Add позже. Поэтому, когда появляется второй клик, вы Dispose его, а затем добавляете его снова вместе с новой панелью. После третьего щелчка вы Dispose второй, и теперь ваш список содержит 2 панели и один новый. Все они вы добавляете в pan и т.д.

Таким образом, в основном вы собираете расположенные панели в списке skillPanels а затем продолжаете читать их в pan.Controls в цикле for, несмотря на то, что они были удалены.

Не знаете, для чего вам нужен список - вы можете просто добавить новую панель в btnAddSkill_Click напрямую. Другая возможность - удалить их из вашего списка, либо после добавления его в pan.Controls либо когда вы их pan.Controls.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню