У меня есть программа, которая добавляет небольшие 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)));
}
}
}
Когда вы добавляете панель в свой список skillPanels
она остается там, даже когда вы добавляете ее с pan.Controls.Add
позже. Поэтому, когда появляется второй клик, вы Dispose
его, а затем добавляете его снова вместе с новой панелью. После третьего щелчка вы Dispose
второй, и теперь ваш список содержит 2 панели и один новый. Все они вы добавляете в pan
и т.д.
Таким образом, в основном вы собираете расположенные панели в списке skillPanels
а затем продолжаете читать их в pan.Controls
в цикле for
, несмотря на то, что они были удалены.
Не знаете, для чего вам нужен список - вы можете просто добавить новую панель в btnAddSkill_Click
напрямую. Другая возможность - удалить их из вашего списка, либо после добавления его в pan.Controls
либо когда вы их pan.Controls
.
FlowLayoutPanel
. Это не будет автоматом. Вы могли бы накапливать ручки.