如何在 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去抓取最新值
我正在尝试动态创建一些标签和按钮。我想在动态创建的按钮单击时更改标签的名称。当我写 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去抓取最新值