Home > database >  How to change dynamically created label text on dynamically created button click in C# Windows Forms
How to change dynamically created label text on dynamically created button click in C# Windows Forms

Time:11-22

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

CodePudding user response:

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

CodePudding user response:

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";
  • Related