From: Rich P on
Lets say I have 50 panels on a form and a button on each panel. Rather
than write 50 click events (one for each button) I would like to write
one event which would be triggered by any of the 50 buttons.

Each panel displays different graphical information. When I click a
button on a respective panel I want to retrieve the underlying graph
data for that panel. I am thinking I could create a button array and
set the same click event to each button in the array and then determine
which button was clicked by checking the sender object (event arg e
...). Is there a more correct or effective way to do this?

Thanks

Rich

*** Sent via Developersdex http://www.developersdex.com ***
From: Jeff Johnson on
"Rich P" <rpng123(a)aol.com> wrote in message
news:uyk8qbNiKHA.5608(a)TK2MSFTNGP05.phx.gbl...

> Lets say I have 50 panels on a form and a button on each panel. Rather
> than write 50 click events (one for each button) I would like to write
> one event which would be triggered by any of the 50 buttons.
>
> Each panel displays different graphical information. When I click a
> button on a respective panel I want to retrieve the underlying graph
> data for that panel. I am thinking I could create a button array and
> set the same click event to each button in the array and then determine
> which button was clicked by checking the sender object (event arg e
> ..). Is there a more correct or effective way to do this?

Everything sounds good except I question the need for the button array. You
could just put a value in the Tag property of each button and then examine
that (from the sender argument).


From: Jeff Gaines on
On 29/12/2009 in message <uyk8qbNiKHA.5608(a)TK2MSFTNGP05.phx.gbl> Rich P
wrote:

>I am thinking I could create a button array and
>set the same click event to each button in the array and then determine
>which button was clicked by checking the sender object (event arg e
>..). Is there a more correct or effective way to do this?

The Tag property of the Button can be useful in situations like this - you
can set it to anything as long as you cast it correctly when retrieving
it. At its simplest it could be a unique integer representing each button.

--
Jeff Gaines Dorset UK
That's an amazing invention but who would ever want to use one of them?
(President Hayes speaking to Alexander Graham Bell on the invention of the
telephone)
From: Peter Duniho on
Rich P wrote:
> Lets say I have 50 panels on a form and a button on each panel. Rather
> than write 50 click events (one for each button) I would like to write
> one event which would be triggered by any of the 50 buttons.
>
> Each panel displays different graphical information. When I click a
> button on a respective panel I want to retrieve the underlying graph
> data for that panel. I am thinking I could create a button array and
> set the same click event to each button in the array and then determine
> which button was clicked by checking the sender object (event arg e
> ...). Is there a more correct or effective way to do this?

Well, the "more correct" way to do it is to not have 50 panels in a
single form. :)

But, even with fewer panels, the underlying question is perfectly valid,
so let's work on that.

First, a terminology issue: the "event" is the actual thing in a class
that you subscribe to. You don't "write" the events; you write the
"event handlers". I think I understand what you mean � you want to
write a single event handler and reuse it for each button � but it's
better if you use the correct terminology in the first place, so that
others don't have to make assumptions to understand your posts.

Now, with that assumption in mind, how to implement a single event
handler that you can apply to each Button in each Panel? There are a
couple of approaches I like to use in this scenario, depending on what
information is available. It's not clear from your post how your
objects are related; in particular, while it's easy enough to get the
Panel for a given Button (it's just that Button's parent object), unless
you already have a way to map from the Panel to the graph data, that
doesn't necessarily solve your issue.

But the simplest way is in fact when you already have a way to get
directly from a Panel instance to the graph data. In that case, your
event handler looks like this:

void GeneralPurposeClickHandler(object sender, EventArgs e)
{
Control ctl = (Control)sender;
Panel panel = (Panel)ctl.Parent;

// retrieve graph data from "panel" as appropriate
// and do whatever processing you want to do
}

Then you just make "GeneralPurposeClickHandler" the event handler for
each Button object.

An alternative way is to take advantage of anonymous methods and
hard-code an argument passed by an anonymous method for each Click
handler to a method that needs that information. This is actually a bit
like writing a new event handler for each Button, but the code is
simpler and easier to keep all in one place.

An example of that approach would be something like this:

class Form1 : Form
{
GraphData[] _data = /* ...initialized as appropriate... *;

public Form1()
{
InitializeComponent();

button1.Click += (sender, e) =>
GeneralPurposeClickHandler(sender, e, _data[0]);
button2.Click += (sender, e) =>
GeneralPurposeClickHandler(sender, e, _data[1]);
button3.Click += (sender, e) =>
GeneralPurposeClickHandler(sender, e, _data[2]);
// etc.

}

void GeneralPurposeClickHandler(object sender, EventArgs e,
GraphData gd)
{
Control ctl = (Control)sender;
Panel panel = (Panel)ctl.Parent;

// No need to retrieve the graph data from the "panel".
// It's been passed to the method as the third argument.
}
}

I like the latter approach in that I find it simple to implement, and
easier to read. But, it can get a bit tedious to do if you wind up with
a large number of event handlers you have to include, since of course
you are in a sense writing a new event handler for each control (each
"(sender, e) => GeneralPurposeClickHandler(sender, e, _data[x]);" is
basically a new method). If you can create a convenient data mapping
from each Panel instance to the appropriate GraphData instance, then the
former approach can work very well, and has the added benefit that there
really is only just the one method ever.

Pete
From: Rich P on
thanks all for your replies. I will note the tagging method, but the
anonymous method seems a little more straight forward. All very nice.
Thanks all.

Rich

*** Sent via Developersdex http://www.developersdex.com ***
 |  Next  |  Last
Pages: 1 2 3
Prev: ExecuteScalar
Next: Fluent interface