472,954 Members | 1,399 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,954 software developers and data experts.

How to select an arbitrary area on a form using sender / what EventHandler?

I have a form, Form6, that has a bunch of buttons overlaid on it. I
want to be able to click on any arbitrary area of the form, and if
that area of the form is overlaid by a button, I want to change the
color of the button to Coral, and show a MessageBox with the button
name.

So far, I've tried the below event handlers, and the only one that has
worked is of course the named button event click, for a particular
named button (button3 below), but, I don't want to set up such click
events for each button, since the form Form6 has an arbitrary number
of buttons and/or a large number of buttons on it.

Any way to do this in C#?

Thanks

RL

//////////

private void Form6_DoubleClick(object sender, EventArgs e)
{
//double clicking on form will cause this event to
trigger, which checks to see if a particular button clicked
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button doubleclicked is: " +
currentButton.Text);
}
}

private void Form6_MouseDoubleClick(object sender,
MouseEventArgs e)
{
//double clicking on form will cause this event to
trigger, which checks to see if a particular button clicked
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button doubleclicked is: " +
currentButton.Text);
}
}

private void Form6_MouseMove(object sender, MouseEventArgs e)
{
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button MouseMove: " +
currentButton.Text);
}

}

private void button3_Click(object sender, EventArgs e) //only
this event handler works
{
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button #3!: " + currentButton.Text);
}

}

private void Form6_MouseDown(object sender, MouseEventArgs e)
{
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button MouseDown: " +
currentButton.Text);
}
}

Jul 25 '08 #1
5 1642
This code in your form should do what you want, if I understand correctly.

public Form1()
{
InitializeComponent();

foreach (Control c in Controls)
{
if (c is Button)
{
Button b = (Button)c;
b.Click += new EventHandler(b_Click);
}
}
}

void b_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
Color old = b.ForeColor;
b.ForeColor = Color.Coral;
MessageBox.Show(b.Name);
b.ForeColor = old;
}

"raylopez99" <ra********@yahoo.comwrote in message
news:af**********************************@a1g2000h sb.googlegroups.com...
>I have a form, Form6, that has a bunch of buttons overlaid on it. I
want to be able to click on any arbitrary area of the form, and if
that area of the form is overlaid by a button, I want to change the
color of the button to Coral, and show a MessageBox with the button
name.

So far, I've tried the below event handlers, and the only one that has
worked is of course the named button event click, for a particular
named button (button3 below), but, I don't want to set up such click
events for each button, since the form Form6 has an arbitrary number
of buttons and/or a large number of buttons on it.

Any way to do this in C#?

Thanks

RL

//////////

private void Form6_DoubleClick(object sender, EventArgs e)
{
//double clicking on form will cause this event to
trigger, which checks to see if a particular button clicked
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button doubleclicked is: " +
currentButton.Text);
}
}

private void Form6_MouseDoubleClick(object sender,
MouseEventArgs e)
{
//double clicking on form will cause this event to
trigger, which checks to see if a particular button clicked
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button doubleclicked is: " +
currentButton.Text);
}
}

private void Form6_MouseMove(object sender, MouseEventArgs e)
{
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button MouseMove: " +
currentButton.Text);
}

}

private void button3_Click(object sender, EventArgs e) //only
this event handler works
{
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button #3!: " + currentButton.Text);
}

}

private void Form6_MouseDown(object sender, MouseEventArgs e)
{
if (sender.GetType() ==
typeof(System.Windows.Forms.Button))
{
Button currentButton = (Button)sender;
currentButton.BackColor = Color.Coral;
MessageBox.Show("Button MouseDown: " +
currentButton.Text);
}
}
Jul 26 '08 #2
On Jul 25, 8:01*pm, "Family Tree Mike"
<FamilyTreeM...@ThisOldHouse.comwrote:
This code in your form should do what you want, if I understand correctly..
Yes, thanks FTM! It worked fine. Just to complicate things and as a
teaching exercise to show for me how delegates work, I added a helper
function that is based on a user defined delegate. The helper
function shows a MessageBox with the button's name, when the button is
clicked. I used two different delegate/event based variables, one
being static, the other being non-static, to fire this helper
function.

It's interesting that you cannot define easily name a delegate Click
since there is a Click delegate (namely, the standard button click
event) already named in .NET, so it's forbidden to do so (compiler
error) unless you want to overload Click, which I don't want to touch,
so I used another delegate name. The location of the 'firing' of the
non-static and static-versions of the event is the same, but the
'registration' of the event is different for non-static (must be
declared once) versus static (must be declared inside of the _Click
function).

Below is the code.

RL

// 7/26/2008
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace MDIForms
{

public partial class Form6 : Form
{
public delegate void ShowNameButEventHandler(object source,
EventArgs e);

//instance class version
public class ButtonHelper
{
public event ShowNameButEventHandler ShowNameBut;
public void OnShowNameBut(Button be, EventArgs e)
{
if (ShowNameBut != null) ShowNameBut(be,
EventArgs.Empty);
}

}

//static class version
public static class staticButtonHelper
{
public static event ShowNameButEventHandler
staticShowNameBut;
public static void staticOnShowNameBut(Button be,
EventArgs e)
{
if (staticShowNameBut != null) staticShowNameBut(be,
EventArgs.Empty);
}
}

Button[] buttons; //Button must be declared here to have
proper scope

/*
// *&* public event EventHandler Click; //not needed since
system has one predefined nongeneric EventHandler delegate called
“Click” already (button click), hence get compiler warning:
'MDIForms.Form6' already contains a definition for 'b_Click'
*/

public Form6()
{
InitializeComponent();
buttons = new Button[] { this.button1,
this.button2,this.button3,this.button4,this.button 5,this.button6,this.button7,this.button8,this.butt on9 };
//buttons 1-9 created using designer wizard prior to runtime

ButtonHelper buttonHelper = new ButtonHelper();

staticButtonHelper.staticShowNameBut += new
ShowNameButEventHandler(buttonHelper_ShowNameBut);

/*
//registration (old-style format); placing registration here is
mandiatory for static version // to prevent more than once
instantiation (compare with non-static version)
*/

foreach (Control c in Controls) //note convention
{
if (c is Button)
{
Button b = (Button)c;
//note convention "Click" is Delegate for signature function "_Click"

b.Click += b_Click; //new style registration;
// b.Click += new EventHandler(b_Click); //oldstyle format also
works

/*
// staticButtonHelper.staticShowNameBut += new
ShowNameButEventHandler(buttonHelper_ShowNameBut); //register,(modern
style) but don't register here--get nine instances!
// buttonHelper.ShowNameBut +=new
ShowNameButEventHandler(buttonHelper_ShowNameBut); //works but should
not be registered here...you get nine popup Message boxes when form
constructed, not what you want
*/

// buttonHelper.OnShowNameBut(b,EventArgs.Empty);
//works but should not be fired here…get up to nine instances of
MessageBox

}
}

}
void b_Click(object sender, EventArgs e) {
Button b = (Button)sender;
Color old = b.BackColor;
b.BackColor = Color.Coral;

// NON-STATIC VERSION OF EVENT (works fine)
// ButtonHelper buttonHelper1 = new ButtonHelper(); //
create instances of ButtonHelper for non-static version of event
delegate
// buttonHelper1.ShowNameBut += new
ShowNameButEventHandler(buttonHelper_ShowNameBut); //register the non-
static public event
// buttonHelper1.OnShowNameBut(b, EventArgs.Empty); //fire
here, non-static instance version (works)

//STATIC VERSION OF EVENT (works fine)
// staticButtonHelper.staticShowNameBut += buttonHelper_ShowNameBut;
//WRONG PLACE TO register static version (gives up to nine
instantiations, everytime the loop is traversed another added)
staticButtonHelper.staticOnShowNameBut(b, EventArgs.Empty);
//fire here, static version;

/*
// both static and non-satic versions of ButtonHelper fired from
inside b_Click, which is automatically fired when buttons are clicked
(depends on button click, see *&* above)
*/

}

//static member function used by delegate/events (same for both static
and non-static delegate/events
static void buttonHelper_ShowNameBut(object sender, EventArgs
e)
{
Button b = (Button)sender;
MessageBox.Show(b.Name + "!");
}

} //end bracket, form 6
} //end bracket, namespace
Jul 26 '08 #3
On Jul 26, 3:37*am, raylopez99 <raylope...@yahoo.comwrote:
On Jul 25, 8:01*pm, "Family Tree Mike"

<FamilyTreeM...@ThisOldHouse.comwrote:
This code in your form should do what you want, if I understand correctly.

Yes, thanks FTM! *It worked fine. *Just to complicate things and as a
teaching exercise to show for me how delegates work, I added a helper
function that is based on a user defined delegate. *The helper
function shows a MessageBox with the button's name, when the button is
clicked. *I used two different delegate/event based variables, one
being static, the other being non-static, to fire this helper
function.

UPDATE: the non-static version works much better. The static version
has a 'bug' that results from the fact the 'static' class is not
garbage collected when the window closes (this happens to be a sub-
form or child window). Then, when you reopen the child window again,
the non-static class has delegate instances that necessitate in
multiple firings. Everytime you close and reopen the window,more of
these delegates accumulate, to the point where if you open and close
the window 10 times, you'll have to click through 10 MessageBoxes for
each time you click on a button.

But the non-static version doesn't have this problem, since the
instance class is garbage collected when the window is closed.

RL

Jul 26 '08 #4
On Jul 26, 4:03*am, raylopez99 <raylope...@yahoo.comwrote:
But the non-static version doesn't have this problem, since the
instance class is garbage collected when the window is closed.

RL
The static version apparently also has to be garbage collected, and is
not being done so properly, refer to some other threads here,
".The object isn't static, it's only the reference to the object that
is static. The object is allocated on the heap just like any other
object, and if you remove the reference from the static variable (e.g.
setting it to null), the object can be garbage collected."

RL
Jul 27 '08 #5
On Jul 27, 5:03*am, raylopez99 <raylope...@yahoo.comwrote:
On Jul 26, 4:03*am, raylopez99 <raylope...@yahoo.comwrote:
But the non-static version doesn't have this problem, since the
instance class is garbage collected when the window is closed.
RL

The static version apparently also has to be garbage collected, and is
not being done so properly, refer to some other threads here,
".The object isn't static, it's only the reference to the object that
is static. The object is allocated on the heap just like any other
object, and if you remove the reference from the static variable (e.g.
setting it to null), the object can be garbage collected."

RL
Here is how I fixed the static version bug, without having to resort
to Dispose, which I hate to fool with.

Simply 'unsubscribe' the event when the subform / child form, Form 6,
closes, like so:

private void Form6_FormClosing(object sender,
FormClosingEventArgs e)
{
staticButtonHelper.staticShowNameBut -=
buttonHelper_ShowNameBut; //dispose of this (to prevent multiple
instances for static version) //works!

}

Now, when you reopen the form, you will only have one static Event/
Event hander/ delegate, and the program will work properly.

This is done automatically in the non-static version, when the
instantiated object, variable buttonHelper1, goes out of scope, but
for the static version you have to manually get rid of the variable as
per the above.

RL
Jul 27 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Bil Muh | last post by:
Esteemede Developers, I would like to Thank All of You in advance for your sincere guidances. I am developing a software using Visual C++ .NET Standard Edition with Windows Form (.NET)...
3
by: Chris | last post by:
Hi, I'm trying to append text from another class to a generic richTextBox that I've added to a Windows form. I can't seem to figure out how to expose the richTextBox to append text to it. ...
6
by: Claus Holm | last post by:
I'm trying to enable a menuitem in the parent form from a mdichild. Rather than making the menuitems public, I'd go for a public method in the parent form to do the change, but when I call the...
8
by: Bil Muh | last post by:
Esteemede Developers, I would like to Thank All of You in advance for your sincere guidances. I am developing a software using Visual C++ .NET Standard Edition with Windows Form (.NET)...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.