Child elements events listener - c#

On a C# Winform application. Imagine that I have a Panel with some labels inside.
How can I listen all click events from this labels in Panel click event?

You can do this programmatically by calling the following code in your Form_Load event handler or any other suitable event handler.
foreach (Label label in panel1.Controls.OfType<Label>())
{
label.Click += LabelOnClick;
}
And then perform your operations in the event handler:
private void LabelOnClick(object sender, EventArgs eventArgs)
{
MessageBox.Show("Label In Panel Clicked");
}

Why not add a extra event handler to all the Control of Type Button within a Panel?
Sample Code :
private void SetupButtonClickListenerForPanel1()
{
panel1.Click += ListenForAllButtonClickOnPanel1;
foreach (Control control in panel1.Controls)
{
var tb = control as Button;
if (tb != null)
{
tb.Click += ListenForAllButtonClickOnPanel1;
}
}
}
private void ListenForAllButtonClickOnPanel1(object sender, EventArgs eventArgs)
{
//
Button tb = (Button) sender; // casting will fail if click is on Panel1 itself!
MessageBox.Show(tb.Name);
}
Linq way to add Handler :
private void SetupButtonClickListenerForPanel1()
{
panel1.Click += ListenForAllButtonClickOnPanel1;
foreach (var tb in panel1.Controls.OfType<Button>())
{
tb.Click += ListenForAllButtonClickOnPanel1;
}
}

If your Labels are children of the panel, a listener for the Click Event on the panel will listen all non redefined listeners of his children.
Example Code:
{
//Form init
panel1.Click += new System.EventHandler(this.panel1_Click);
....
}
private void panel1_Click(object sender, EventArgs e)
{
//The clicked label will be sender.
Label l = (Label) sender; //Should be a safe cast. Will crash if sender is not a label
}

Related

C#: How to MouseHover on a group of objects and MouseLeave event when you leave the entire group [duplicate]

This question already has an answer here:
How can a hover effect be created for a grouping of controls?
(1 answer)
Closed 4 years ago.
I have a few objects in a groupBox in Visual Studio such as a few buttons. I have a label that pops up when I enter the groupBox and disappears when I leave it. However, when I hover over a button in this groupBox, the label disappears as the MouseLeave event only corresponds to the groupBox.
Is there anyway to have all of these objects grouped together so when I hover on anything in the groupBox the label stays and when I leave the groupBox altogether the label disappears? I just want an elegant way to do this.
Thanks so much for your help!
This is different than How can a hover effect be created for a grouping of controls? because I'd like a different result than what this person wants and also I tried something similar and it didn't work.
Unfortunately you can not add objects by groupbox but you can add them as a list of the control type of itself.
here you go.
private void Form1_Load(object sender, EventArgs e)
{
TextBox[] textboxes = new TextBox[] { textBox1 , textBox2, textBox3 };
Button[] buttons = new Button[] { button1 };
foreach (TextBox tbox in textboxes)
{
tbox.MouseEnter += new System.EventHandler(textbox_MouseEnter);
tbox.MouseLeave += new System.EventHandler(textbox_MouseLeave);
}
foreach (var button in buttons)
{
button.MouseEnter += new System.EventHandler(btn_MouseEnter);
button.MouseLeave += new System.EventHandler(btn_MouseLeave);
}
}
private void btn_MouseEnter(object sender, System.EventArgs e)
{
var Button = (Button)sender;
button1.BackColor = Color.Red;
//label show
}
private void btn_MouseLeave(object sender, System.EventArgs e)
{
var Button = (Button)sender;
button1.BackColor = SystemColors.Control;
//label hide
}
private void textbox_MouseEnter(object sender, System.EventArgs e)
{
var textbox = (TextBox)sender;
textbox.BackColor = Color.Red;
//label show
}
private void textbox_MouseLeave(object sender, System.EventArgs e)
{
var textbox = (TextBox)sender;
textbox.BackColor = SystemColors.Control;
//label hide
}
GIF IMAGE OF WORKING : GIF
You could do something like this,
//Add new event handlers on appropriate location in your code (perhaps in the load event of the form?)
groupBox1.MouseEnter += new EventHandler(MouseEnteredGroupBox);
groupBox1.MouseLeave += new EventHandler(MouseLeftGroupBox);
In the MouseEnter event handler you change the state of your controls which you want to show.
private void MouseEnteredGroupBox(object sender, EventArgs e)
{
//Add controls to be shown when entering the groupbox
button1.Visible = true;
}
Add this method to check if your cursor is inside of your groupbox area
private bool IsAboveGroupBox(GroupBox gb)
{
Point cursorPos = PointToClient(Cursor.Position);
bool resultX = (cursorPos.X > gb.Location.X && cursorPos.X < gb.Location.X + gb.Size.Width) ? true : false;
bool resultY = (cursorPos.Y > gb.Location.Y && cursorPos.Y < gb.Location.Y + gb.Size.Height) ? true : false;
return resultX && resultY;
}
Finally in the MouseLeave event handler you call the method
private void MouseLeftGroupBox(object sender, EventArgs e)
{
if (!IsAboveGroupBox(sender as GroupBox))
{
//Add controls to be hidden when leaving the groupbox
button1.Visible = false;
}
}
EDIT: Else you could just view your controls on the MouseEnter event on groupbox and hide your controls on the Forms MouseEnter event?

How to create and call dynamically instantiated methods in C#? [duplicate]

I am creating one button on a page dynamically. Now I want to use the button click event on that button.
How can I do this in C# ASP.NET?
Button button = new Button();
button.Click += (s,e) => { your code; };
//button.Click += new EventHandler(button_Click);
container.Controls.Add(button);
//protected void button_Click (object sender, EventArgs e) { }
The easier one for newbies:
Button button = new Button();
button.Click += new EventHandler(button_Click);
protected void button_Click (object sender, EventArgs e)
{
Button button = sender as Button;
// identify which button was clicked and perform necessary actions
}
Simply add the eventhandler to the button when creating it.
button.Click += new EventHandler(this.button_Click);
void button_Click(object sender, System.EventArgs e)
{
//your stuff...
}
It is much easier to do:
Button button = new Button();
button.Click += delegate
{
// Your code
};
You can create button in a simple way, such as:
Button button = new Button();
button.Click += new EventHandler(button_Click);
protected void button_Click (object sender, EventArgs e)
{
Button button = sender as Button;
// identify which button was clicked and perform necessary actions
}
But event probably will not fire, because the element/elements must be recreated at every postback or you will lose the event handler.
I tried this solution that verify that ViewState is already Generated and recreate elements at every postback,
for example, imagine you create your button on an event click:
protected void Button_Click(object sender, EventArgs e)
{
if (Convert.ToString(ViewState["Generated"]) != "true")
{
CreateDynamicElements();
}
}
on postback, for example on page load, you should do this:
protected void Page_Load(object sender, EventArgs e)
{
if (Convert.ToString(ViewState["Generated"]) == "true") {
CreateDynamicElements();
}
}
In CreateDynamicElements() you can put all the elements you need, such as your button.
This worked very well for me.
public void CreateDynamicElements(){
Button button = new Button();
button.Click += new EventHandler(button_Click);
}
Let's say you have 25 objects and want one process to handle any one objects click event. You could write 25 delegates or use a loop to handle the click event.
public form1()
{
foreach (Panel pl in Container.Components)
{
pl.Click += Panel_Click;
}
}
private void Panel_Click(object sender, EventArgs e)
{
// Process the panel clicks here
int index = Panels.FindIndex(a => a == sender);
...
}

How to create the event handler for editing dynamic labels in C#?

I have created a dynamic label on button click on Windows Form. And then on a right click on the label. I'm showing a context menu "cm". I obviously want to add functionality to the context menu items. But what I don't understand is how do I reference the "lbl" object inside the event handler? How can I edit the properties of the labels from inside the event handlers named MarkedImportant and EditLabel?
public void btnMonSub_Click(object sender, EventArgs e)
{
string s = txtMonSub.Text;
Label lbl = new Label();
lbl.Text = s;
lbl.Location = new System.Drawing.Point(205 + (100 * CMonSub), 111);
CMonSub++;
lbl.Size = new System.Drawing.Size(100, 25);
lbl.BackColor = System.Drawing.Color.AliceBlue;
this.Controls.Add(lbl);
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Mark Important", MarkImportant);
cm.MenuItems.Add("Edit", EditLabel );
lbl.ContextMenu = cm;
}
private void MarkImportant(object sender, EventArgs e)
{
// imp..
}
private void EditLabel(object sender, EventArgs e)
{
// edit..
}
Or is there a better way to do this? Like dynamically adding the event handler itself?
Thanks in advance.
The ContextMenu has a property called SourceControl and MSDN says it
Gets the control that is displaying the shortcut menu.
So your event handler could reach the ContextMenu from the MenuItem passed as the sender parameter in this way
private void MarkImportant(object sender, EventArgs e)
{
// Convert the sender object to a MenuItem
MenuItem mi = sender as MenuItem;
if(mi != null)
{
// Get the parent of the MenuItem (the ContextMenu)
// and read the SourceControl as a label
Label lbl = (mi.Parent as ContextMenu).SourceControl as Label;
if(lbl != null)
{
....
}
}
}

How to put new eventhandle on existing buttons c#?

I want to put on existing button new event handle. I have 9 buttons created in form and want to display each name when is clicked on it, but don't want to put on every button message manually.
How to accomplish that?
You can use the sender propperty of the EventHandler in order to do that. This example uses winforms buttons:
SomeButtonClicked(object sender, EventArgs e)
{
var button = sender as Button;
MessageBox.Show(button.Name);
}
And then you can add this event to multiple buttons i.e.:
button1.Click += new System.EventHandler(SomeButtonClicked);
button2.Click += new System.EventHandler(SomeButtonClicked);
button3.Click += new System.EventHandler(SomeButtonClicked);
You can code something like this
private void MainForm_Load(object sender, EventArgs e) {
...
// Assigning on click event, assuming that all your buttons are on the MainForm
foreach (Control ctrl in Controls) {
Button btn = ctrl as Button;
if (!Object.ReferenceEquals(null, btn))
btn.Click += onButtonClick;
}
...
// On click itself
private void onButtonClick(Object sender, EventArgs e) {
Button btn = sender as Button;
String name = btn.Name; // <- Or whichever property of the button you want
}

Dynamicly added Controls [e.g Button] : How to add events and Access

At my program i dynamicly add Buttons to my form
{
...
Button bt = new Button();
bt.Text = "bla bla";
bt.MouseClick += new MouseEventHandler(bt_MouseClick);
myPanel.Controls.Add(bt);
...
}
void bt_MouseClick(object sender, MouseEventArgs e)
{
TabPage _tab = new TabPage();
_tab.Text = ??? // I want to get the Button's text ! this.Text returns me the
//main form.Text
}
How can access my dynamic Buttons properties ? How can I understand whick button is
clicked either getting its text.
Thanks.
void bt_MouseClick(object sender, MouseEventArgs e)
{
TabPage _tab = new TabPage();
_tab.Text = ((Button)sender).Text;
}
When an EventHandler delegate is invoked, the sender parameter is the component that raised the event, and the e parameter is a subclass of EventArgs that provides any additional component/event specific information for the event.
Therefore you can establish which button the event fired on by casting the sender parameter to Button:
void bt_MouseClick(object sender, MouseEventArgs e)
{
var button = (Button)sender;
TabPage _tab = new TabPage();
_tab.Text = button.Text;
}

Categories