如何在 C# Windows Forms 应用程序中单击动态创建的按钮更改动态创建的标签文本

How to change dynamically created label text on dynamically created button click in C# Windows Forms application

我正在尝试动态创建一些标签和按钮。我想在动态创建的按钮单击时更改标签的名称。当我写 button_click 方法时,我无法直接访问标签对象。我该怎么做?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DemoPanel
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            int lblYVal = 10;
            int btnYVal = 50;

            for(int i = 1; i< 5; i++)
            {
                Label lbl = new Label();
                lbl.Text = "test";
                lbl.Name = "test"+i.ToString();
                lbl.Location = new System.Drawing.Point(10, lblYVal);
                lbl.Visible = true;

                Button btn = new Button();
                btn.Text = "Click";
                btn.Name = "textBtn" + i.ToString();
                btn.Location = new System.Drawing.Point(10,btnYVal);
                btn.Visible = true;

                btn.Click += new EventHandler(this.btn_click);


                this.Controls.Add(lbl);
                this.Controls.Add(btn);
                lblYVal += 70;
                btnYVal += 70;
                

            }

        }

        void btn_click(object sender, EventArgs e)
        {
            //How can i change label text from here.
            //lbl.text //Does Not exist Error.
            Label lbl = new Label();
            lbl.Text = "New text"; //Not changing Label text
        }
    }
}

您可以维护一个按钮到标签的字典,并使用它来查找匹配的标签。另一种选择是将索引与按钮和标签相关联,并用它找到标签。

我将向您说明字典选项。

Dictionary<Button, Label> mapping = new Dictionary<Button, Label>();

...

在你的循环中,

mapping[btn] = lbl;

在您的处理程序中,

((Label)mapping[(Button)sender)]).Text = "some text";

您编写的 for 循环知道按钮和标签。您可以利用它来编写捕获标签的点击处理程序。就像改变一样简单:

btn.Click += new EventHandler(this.btn_click);

btn.Click += (sender, args) => lbl.Text = "Clicked";

不必这么短。例如,你可以这样做:

btn.Click += (sender, args) => {
  if(something > 0)
    lbl.Text = "Did the process because something was > 0";
  else
    lbl.Text = "Can't start the process because something is 0";
}

或者如果你有一个“做事”的方法

void DoTheProcessAndOutputToTheLabel(Label x){
  int i = 0;
  foreach(var thing in things){
    bool success = ProcessTheThing(thing);
    if(success)
      i++;
  }
  x.Text = $"Processed {i} things";
}

btn.Click += (sender, args) => DoTheProcessAndOutputToTheLabel(lbl);

不太确定,在你的评论中你说“使用发件人”,但这里这个事件处理程序只附加到一个按钮,所以你真的不需要对发件人做任何事情,因为很明显哪个发件人是.例如,您可能有:

btn.Tag = "hello"+i;
btn.Click += (sender, args) => DoTheProcessAndOutputToTheLabel(lbl, (sender as Control).Tag);

它将发送单词“hello2”作为参数(如果它是循环的第二次)..但实际上因为你知道发件人你可以形成任何东西:

var x = "hello"+i;
btn.Click += (sender, args) => DoTheProcessAndOutputToTheLabel(lbl, x);

我只预见发件人,但如果其他东西改变了你设置和用户点击按钮之间的 UI - 例如,如果他们 运行 一个改变按钮标签的过程, 那么确定, 使用sender去抓取最新值