jerin sifat
jerin sifat

Reputation: 67

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

I am trying to create some labels and buttons dynamically. I want to change the label's name on dynamically crated button click. When I am writing the button_click method, I can not access the label object directly. How can I do that?

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

Upvotes: 0

Views: 1627

Answers (2)

Caius Jard
Caius Jard

Reputation: 74615

The for loop you've written knows about the button and the label. You can leverage this to write a click handler that captures the label. It's as simple as changing:

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

To

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

It doesn't have to be so short. You could, for example do:

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

Or if you have a method that "does stuff"

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

Not quite sure, in your comment you said "use the sender" but here this event handler only ever attaches to one button so you don't really need to do anything with the sender because it's obvious which sender is is. For example you might have:

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

It will send the word "hello2" in as an argument (if it's the second go of the loop).. but realistically because you know the sender you could form anything:

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

I only foresee the sender but being useful if something else changes the UI between you setting up and the user clicking the button - for example if they run a process that alters the button Tag, then sure, use the sender to grab the latest value

Upvotes: 1

Tanveer Badar
Tanveer Badar

Reputation: 5522

You can maintain a dictionary of buttons to labels and use that to find the matching label. Another option would be to associate an index with both button and label and find the label with that.

I'll illustrate the dictionary option to you.

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

...

In your loop,

mapping[btn] = lbl;

In your handler,

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

Upvotes: 0

Related Questions