【问题标题】:How to dynamically create buttons and add events to them?如何动态创建按钮并向它们添加事件?
【发布时间】:2016-06-25 12:10:01
【问题描述】:

我有按钮数组和标签数组: Label[] labels = new Label[10]; Button[] but = new Button[10];

在单击另一个按钮时,我想从数组中动态创建新按钮和新标签,我还希望 but[i] 更改标签[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";
    }

但是显然我不能在事件处理程序中放置一个数组,那我应该怎么做呢?

【问题讨论】:

  • 哇真的太棒了“但是[i]_Click”甚至不会想到这样的事情。然而,至少在 c# 中这是不可能的。正题,你用的是WPF还是WinForms?
  • 只有how to fire events dynamicly吗?

标签: c# arrays visual-studio events button


【解决方案1】:

做到这一点的一种方法是让你的方法返回一个处理程序而不是成为一个处理程序:

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 变量。它等同于这个(如果冗长的话,这也是一种有效的方法):

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);

【讨论】:

    【解决方案2】:

    您可以将数组索引作为 Tag 属性添加到按钮,然后在 but_Click 中将其拉回。

    所以,添加

    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"; }
    

    或者使用 Tag 属性的另一个选项,添加:

    but[i].Tag = label[i];
    
    ...
    
    private void but_Click(object sender, EventArgs e)
    {
        Label label = (Label)((Button)sender).Tag;
        label.Text = "Changed Text";
    }
    

    这种方法的优点是您无需在初始创建控件后保持数组同步。

    【讨论】:

      【解决方案3】:

      我想这是不言自明的:

      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...
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-24
        • 2012-07-08
        • 2013-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多