Prev: ExecuteScalar
Next: Fluent interface
From: Rich P on 29 Dec 2009 17:33 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 29 Dec 2009 17:47 "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 29 Dec 2009 17:52 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 29 Dec 2009 18:10 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 29 Dec 2009 18:55
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 *** |