前段时间由于事情比较多,很长时间没有进行学习和知识的总结,几天有空刚好补上!
今天要讲的是怎样实现控件的动态生成和删除:
1.首先,我们创建一个新的窗体,使用一个panel控件(控件的Dock属性设置为top或Fill)作为整个容器,在该panel控件再创建一个panel控件(控件属性设置为Fill),然后在该控件内部拖入两个dateTimePicker控件和一个TextBox控件和两个label控件,将它们从左到右依次排成一排,最后效果如图1所示:
图1
2.关于点击"+"按钮,动态生成控件的代码实现如下:
private void label1_Click(object sender, EventArgs e)
{
Label lb = (Label)sender;
//lb.Parent.BackColor = Color.Red;
//ControlHelper是一个控件复制类,clone是类中的复制方法
Control gb = ControlHelper.Clone(lb.Parent, true) as Control;
//Control cp_lb_First_Menu = cp_pn_MenuBlock.Controls.Find(lb_First_Menu.Name, true)[0];
Control lb2 = gb.Controls.Find(label2.Name, true)[0];
Control lb1 = gb.Controls.Find(label1.Name, true)[0];
//lb1.Visible = false;
lb2.Visible = true;
lb1.BackColor = Color.Red;
this.panel1.Controls.Add(gb);
//保证复制后的控件都在原控件下方显示
gb.BringToFront();
}
在上面一段代码中有两个关键点,一是实现控件的复制,二是实现如何控制复制控件的显示位置,以上都进行了注释说明。
此时可以看到效果如图2,3所示:
图2
图3
3.下面是是给生成的控件绑定点击事件的代码:
private void label1_Click(object sender, EventArgs e)
{
Label lb = (Label)sender;
//lb.Parent.BackColor = Color.Red;
Control gb = ControlHelper.Clone(lb.Parent, true) as Control;
//Control cp_lb_First_Menu = cp_pn_MenuBlock.Controls.Find(lb_First_Menu.Name, true)[0];
Control lb2 = gb.Controls.Find(label2.Name, true)[0];
Control lb1 = gb.Controls.Find(label1.Name, true)[0];
//lb1.Visible = false;
lb2.Visible = true;
//动态生成控件按钮绑定事件
lb2.Click += delegate
{
BindClick(gb);
};
//删除控件的按钮绑定事件
lb1.Click += delegate
{
BindAddClick(lb1);
};
lb1.BackColor = Color.Red;
this.panel1.Controls.Add(gb);
//保证复制后的控件都在原控件下方显示
gb.BringToFront();
}
下面是绑定添加控件事件方法的代码:
private void BindAddClick(Control cl)
{
Control gb = ControlHelper.Clone(cl.Parent, true) as Control;
//Control cp_lb_First_Menu = cp_pn_MenuBlock.Controls.Find(lb_First_Menu.Name, true)[0];
Control lb2 = gb.Controls.Find(label2.Name, true)[0];
Control lb1 = gb.Controls.Find(label1.Name, true)[0];
//lb1.Visible = false;
lb2.Visible = true;
lb2.Click += delegate
{
BindClick(gb);
};
lb1.Click += delegate
{
BindAddClick(lb1);
};
lb1.BackColor = Color.Red;
this.panel1.Controls.Add(gb);
//保证复制后的控件都在原控件下方显示
gb.BringToFront();
}
//绑定删除控件事件的代码
private void BindClick(Control cl)
{
//保证如何在删除和添加时能释放资源(即可以紧跟在显示的控件后面显示)
cl.Controls.Clear();
DisposeControls(cl);
//释放资源
cl.Dispose();
}
//在清空控件时如何释放资源
private void DisposeControls(Control cParent)
{
foreach (Control c in cParent.Controls)
{
//DisposeControls(c);
c.Controls.Clear();
c.Dispose();
}
}
注意,删除控件时,必须要释放控件资源,否则只是在表面清除控件,实际添加控件就会发生效果如图4所示:
图4
4.下面介绍一下关于动态生成的控件输入参数如何获取数据,治理只提供一种基本获取数据思路,代码如下:
//如何通过点击获取数据
private void button1_Click(object sender, EventArgs e)
{
//循环读取所有数据
foreach(Control c in this.panel1.Controls)
{
foreach (Control t in c.Controls)
{
if (t.Name == "textBox1")
{
MessageBox.Show(t.Text.ToString());
}
}
}
}
到这里动态生成控件和删除控件也就讲完了。