C# 如何动态创建按钮并向其添加事件?
我有一组按钮和一组标签:C# 如何动态创建按钮并向其添加事件?,c#,arrays,visual-studio,events,button,C#,Arrays,Visual Studio,Events,Button,我有一组按钮和一组标签: 标签[]标签=新标签[10]; 按钮[],但=新按钮[10] 单击另一个按钮时,我希望从数组中动态创建新按钮和新标签,同时我还希望but[I]更改标签的tex[I]: private void button1_Click(object sender, EventArgs e) { labels[i] = new Label(); labels[i].Location = new System.Drawing.Point(
标签[]标签=新标签[10];
按钮[],但=新按钮[10]代码>
单击另一个按钮时,我希望从数组中动态创建新按钮和新标签,同时我还希望but[I]更改标签的tex[I]:
private void button1_Click(object sender, EventArgs e)
{
labels[i] = new Label();
labels[i].Location = new System.Drawing.Point(0, 15+a);
labels[i].Parent = panel1;
labels[i].Text = "Sample text";
labels[i].Size = new System.Drawing.Size(155, 51);
labels[i].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
a = labels[i].Height + labels[i].Top;
but[i] = new Button();
but[i].Text = "-";
but[i].Location = new System.Drawing.Point(0, labels[i].Height + labels[i].Top);
but[i].Parent = panel1;
but[i].Size = new System.Drawing.Size(155, 10);
but[i].Click += new System.EventHandler(but_Click);
i++;
}
private void but[i]_Click(object sender, EventArgs e)
{
labels[i].Text = "Changed Text";
}
但显然我不能将数组放入事件处理程序中,那么我应该如何做呢?我想这是自我解释:
public void SomeMehthod()
{
Button btn1 = new Button();
Button btn2 = new Button();
Button btn3 = new Button();
// Your button-array
Button[] btns = new Button[]
{
btn1,
btn2,
btn3
};
foreach(Button btn in btns)
{
// For each button setup the same method to fire on click
btn.Click += new EventHandler(ButtonClicked);
}
}
private void ButtonClicked(Object sender, EventArgs e)
{
// This will fire on any button from the array
// You can switch on the name, or location or anything else
switch((sender as Button).Name)
{
case "btn1":
// Do something
break;
case "btn2":
// Do something
break;
case "btn3":
// Do something
break;
}
}
或者如果您的阵列可以全局访问:
Button[] btns = new Button[5];
Label[] lbls = new Label[5];
private void ButtonClicked(Object sender, EventArgs e)
{
Button clicked = sender as Button;
int indexOfButton = btns.ToList().IndexOf(clicked);
// ..IndexOf() returns -1 if nothign is found
if(indexOfButton > 0)
{
lbls[indexOfButton].DoWhatYouWant...
}
}
您可以将数组索引作为标记属性添加到按钮中,然后在中将其拉出,但单击
所以,加上
but[i].Tag = i;
到按钮创建。然后更改事件处理程序:
private void but_Click(object sender, EventArgs e)
{
int buttonIndex = (int)((Button)sender).Tag;
labels[buttonIndex].Text = "Changed Text";
}
或者将事件处理程序内联:
but[i].Click += (s,e) => { label[i].Text = "Changed Text"; }
或使用标记属性的其他选项,添加:
but[i].Tag = label[i];
...
private void but_Click(object sender, EventArgs e)
{
Label label = (Label)((Button)sender).Tag;
label.Text = "Changed Text";
}
这种方法的优点是,在初始创建控件后,不依赖于保持数组同步。一种方法是使方法返回一个处理程序,而不是一个处理程序:
private EventHandler but_Click(int i)
{
return (s, e) => labels[i].Text = "Changed Text";
}
然后像这样使用它:
but[i].Click += but_Click(i);
或内联执行:
but[i].Click += (s, ea) => labels[i].Text = "Changed Text";
这两种方法中的任何一种都是一些编译器魔法,可以捕获i
变量。这与此等效(这也是一种有效的方法,如果详细的话):
哇,真是太棒了,“但是我点击”甚至没有想到这样的事情。然而,这至少在c#中是不可能的。对于本主题,您使用的是WPF或WinForms是什么?是否只是关于如何动态触发事件的?
class MyWrapper {
private int i;
public MyWrapper(int i) {
this.i = i;
}
public void TheHandler(object sender, EventArgs e) {
// TODO: capture the object that owns `labels` also, or this won't work.
labels[i].Text = "Changed Text";
}
}
//call with
but[i].Click += new EventHandler(new MyWrapper(i).TheHandler);