Click here to Skip to main content
15,067,250 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
Hey guys I wanna ask how forward event handler for click on dynamic generate buttons. This buttons I generate to flowlayout panel in Form1.cs
I generate usercontrol "btnMini.cs" where I have it 2 button.
How can i forward click event for these buttons from Form1 to UserControl - "btnMini.cs" ?
I wanna after click on button forward and get messagebox.show where is "Parent name of button" and other show me "button name". How can I do it from Form1?
C#
Button btn = (Button)sender; 
MessageBox.Show("Click btn: " + btn.Name + ", Parent name control: " + btn.Parent.Name);

I try this but I dont know how do it when I need create MessageBox.Show in Form1 after Clicking....
Thank you for advice.
I am little hopeless how do it :/ so thanks very body for tips.
show forms design with msgbox.[^]

What I have tried:

btnMini - UserControl which I generate to flowlayoutpanel in Form1.cs
public partial class btnMini : UserControl
    {
        public btnMini()
        {
            InitializeComponent();
        }
        [Browsable(true)]
        [Category("ActionClick")]
        [Description("Invoke when user clicks on button")]
        public event EventHandler ButtonClick;//ok
        
        private void TestingClicks(object sender, EventArgs e)
        {
            ButtonClick?.Invoke(sender, e);
        }
        public void OnClick(object sender, EventArgs e)
        {
            TestingClicks(sender, e);            
        }
}


Form1
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        #region variables
        private int counter = 1;
        private btnMini btnM = new btnMini();
        private List<Control> control = new List<Control>();
        //public event EventHandler ClickTest;
        #endregion

        //Using this method I adding userControl to list
        private void button1_Click(object sender, EventArgs e)
        {
            //Button btn = (Button)sender;
            //MessageBox.Show("Click btn: " + btn.Name + ", Parent name control: " + btn.Parent.Name); //Here I tried do this for get Name of parent and button UserControl - btnMini.cs

            btnM = new btnMini();
            btnM.Name = "btn_" + counter;
            //btnM.OnClick += userControl11_CloseButtonClicked;
            //btnM.Click += (sender, args) => btnM.OnClick(this, e);

            //btnM.ButtonClick += new EventHandler(Btn_Click);;
            //btnM.Click += (sender, args) => btnM.OnClick(this, e);
            //btnM.ButtonClick += btn;
            //btnM.Click += (sender, args) => btnM.ButtonClick?.Invoke(sender, args);
            counter++;
            control.Add(btnM);

        }
       //method for adding UserControl from List.
        private void button2_Click(object sender, EventArgs e)
        {
            foreach (var b in control)
            {
                this.flowLayoutPanel1.Controls.Add(b);
            }
        }
}
Posted
Updated 10-Aug-21 7:46am
Comments
Maciej Los 10-Aug-21 9:04am
   
Sorry, your question is not quite clear... If you want to get parent name, you can use something like that (in Click_event):
Button b = sender as Button;
MessageBox.Show(b.Parent.Name);
Beji_ 10-Aug-21 9:14am
   
I know I try using this but how do it for generate usercontrol? I
Using button1 in Form1 I generate UserMini to list of control so my proble is how add this generate click event now.

BtnMini btnM=new btnMini();
btnm.Click += //eventhandler from like you say Button b=sender as Button; how do it ??

Please ask yourself if you intend to write code only you will understand: if the answer is "no," read on. If you want to get a job as a programmer in the future, please read on.

A UserControl is a ContainerControl; so is a FlowLayoutPanel. You add Controls to the ControlCollection of a ContainerControl, and the ContainerControl can be accessed from the added Controls by their Parent Property (which returns a generic Control instance).

Consider the way elements are named and used in this example:
//'Form1 main Form

//'btnAddBtnContainer eventhandler: adds a new BtnContainer usercontrol to FlowLayoutPanel
// and then adds a Button to the UserControl.

//'BtnToBtnContainer dictionary maps buttons to their Parent's native Type

//'BtnContainer usercontol with no controls inside it

// 'flowLayOutPanel1 FlowLayoutPanel

        private Dictionary<Button, BtnContainer> BtnToBtnContainer = new Dictionary<Button, BtnContainer>();

        private int bcntCount = 0;
        private int btnCount = 0;

        private void btnAddBtnContainer_Click(object sender, EventArgs e)
        {
            BtnContainer bcntNew = new BtnContainer();
            bcntNew.Name = $"bcnt_{bcntCount++}";

            Button btnNew = new Button();
            btnNew.Name = $"btn_{btnCount}";
            btnNew.Text = btnCount.ToString();
            btnCount++;

            BtnToBtnContainer.Add(btnNew, bcntNew);

            bcntNew.Controls.Add(btnNew);

            btnNew.Click += BtnNewOnClick;

            flowLayoutPanel1.Controls.Add(bcntNew);
        }

        private void BtnNewOnClick(object sender, EventArgs e)
        {
            Button btn = sender as Button;

            // note @1
            BtnContainer bcnt = BtnToBtnContainer[btn];

            switch (Int32.Parse(btn.Text))
            {
                case 1:
                    break;
                // and ... and ... and
            }
        }
Notes:
1) I used a dictionary here to look up the Parent UserControl; that's kind of a frill since you can easily cast the Parent Property to its native Type; my motive was to to get you thinking about what else you could use a Dictionary (or some other data structure) for in the future.
   
v2
You're passing your Button control to the ButtonClick event as the sender, so you already have access to the button that was clicked. The commented out code you've listed is pretty much there:
C#
btnM.ButtonClick += (s, ev) =>
{
  Button button = s as Button;
  string parent = button?.Parent?.Name;

  if (parent != null)
  {
    // You have the parent name here
  }
}

Note that I've named the parameters s and ev as you already have declared parameters named sender and e
   
Comments
Beji_ 10-Aug-21 9:50am
   
btnM.Click += (s, ev) =>
            {
                Button b = (Button)sender;
                MessageBox.Show(b.Name.ToString());
            };

I try like you show but its worng use like this?
Because I need first generate UserControl btnMini on this image -> IMAGE how I mean[^]
So I after this I wanna generate use it button2. And when i click on generate control (UserControl) I need get from Form1 using event handling Name ot button or parrent.
:/
Chris is right, but a better version of that might be:
C#
btnM.ButtonClick += (s, ev) =>
{
  if (s is Button button)
  {
      ...
  }
}
   
Comments
Beji_ 10-Aug-21 9:56am
   
how can I separete for button1 and button2 ? Because I have it 2 buttons. So if I click on button1 I need get Parent.Name; and if on button2 i need only button.Name;
Now I have it on UserControl(btnMini.cs) have for button1 and button2 I add method OnClick for Click Actions.
Copy Code
public event EventHandler ButtonClick;
private void TestingClicks(object sender, EventArgs e)        {            ButtonClick?.Invoke(sender, e);         }        

public void OnClick(object sender, EventArgs e)        {            TestingClicks(sender, e);}
Beji_ 10-Aug-21 10:21am
   
Nice I trying some stuffand now its doing pretty well. Thanks for help :)
OriginalGriff 10-Aug-21 10:24am
   
You're welcome!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900