Pretty easy question, i'd assume..

  • Thread starter Thread starter Brian
  • Start date Start date
B

Brian

Hello all,

I have an form to Enter a Name with letters from A to Z in buttons.

When you click a button, it should append the text associated with
that button to a text box.

Instead of having an EventHandler for every button with a click event
of:

private void btnA_Click(object sender, System.EventArgs e)
{
txtNameField.AppendText("A");
}

And so on...

Is there a way to shorten this, such as have just the 1 Event Handler
for all buttons? I was thinking something along the lines of this:

private void buttonLetter_Click(object sender, System.EventArgs e)
{
txtNameField.AppendText(letter);
}

private void AppendLetter(letter)
{
txtNameField.AppendText(letter);
}

I hope you realise what i'm talking about here.
 
Brian said:
I have an form to Enter a Name with letters from A to Z in buttons.

When you click a button, it should append the text associated with
that button to a text box.

Instead of having an EventHandler for every button with a click event
of:

private void btnA_Click(object sender, System.EventArgs e)
{
txtNameField.AppendText("A");
}

And so on...

Is there a way to shorten this, such as have just the 1 Event Handler
for all buttons?

Absolutely. Use one event handler, and use the "sender" parameter to
find out which button was pressed.
 
...
I have an form to Enter a Name with letters from A to Z in buttons.

When you click a button, it should append the text associated with
that button to a text box.

Instead of having an EventHandler for every button with a click event
of:

private void btnA_Click(object sender, System.EventArgs e)
{
txtNameField.AppendText("A");
}

And so on...

Is there a way to shorten this, such as have just the 1 Event Handler
for all buttons?

I guess that you have each letter as the Label of the buttons?

In that case you could have a method like:

private void buttonLetter_Click(object sender, System.EventArgs e)
{
Button b = (Button) sender;
txtNameField.AppendText(b.Text);
}

If you have something else in your labels, you could possibly use the Tag
property of the buttons instead.

// Bjorn A
 
Instead of DoubleClick on yout button to create an eventhandler. You can make
an eventhandler bij typing in a name in the propertieswindow.

In the evenhandler you could typecast the sender parameter to a button and
read a
describing property like Text or Tag.

string letter = ((Button)Sender).Tag
 
And if you don't use Visual Studio, you would do this like:

private void btnAll_Click(object sender, System.EventArgs e){
txtNameField.AppendText(((Button)sender).Label);
}


Then in OnInit...

override protected void OnInit(EventArgs e){
btnA.Click += new EventHandler(btnAll_Click);
btnB.Click += new EventHandler(btnAll_Click);
...
base.OnInit(e)
}

You can substitute double clicks if you want, but that would be sort of
annoying.
 
Or, if you really wanna save typing (clicking), you could loop over the
controls on the buttons' container...

System.EventHandler alphaBtnClickHdlr = new
System.EventHandler(alphaButtonClick);
foreach ( Control c in alphaButtonPanel.Controls )
{
if ( c is System.Windows.Form.Button )
{
c.Click += alphaBtnClickHdlr;
}
}

This handles all 26 buttons, plus any additional characters you may decide
you need later. This of course assumes you have a panel with no other other
buttons besides those you want to attach the event to. Alternatively, you
could have way to identify the type (it is a special derived type that has a
property to hold the character to append, or it implements a special
interface.) Then you could check ( c is MySpecialButtonType). Of course,
that would be overkill for what you ask, but I do have an ap with some
special types (each containing a number of custom properties) that implement
a common interface, and I use that kind of structure for it.

Rachel
 
Rachel Suddeth said:
Or, if you really wanna save typing (clicking), you could loop over the
controls on the buttons' container...

System.EventHandler alphaBtnClickHdlr = new
System.EventHandler(alphaButtonClick);
foreach ( Control c in alphaButtonPanel.Controls )
{
if ( c is System.Windows.Form.Button )
{
c.Click += alphaBtnClickHdlr;
}
}

This handles all 26 buttons, plus any additional characters you may decide
you need later. This of course assumes you have a panel with no other other
buttons besides those you want to attach the event to. Alternatively, you
could have way to identify the type (it is a special derived type that has a
property to hold the character to append, or it implements a special
interface.) Then you could check ( c is MySpecialButtonType). Of course,
that would be overkill for what you ask, but I do have an ap with some
special types (each containing a number of custom properties) that implement
a common interface, and I use that kind of structure for it.

I think that rather than generate the event handlers separately, I'd
just generate the buttons and the event handlers in one go:

for (char c = 'A'; c <= 'Z'; c++)
{
Button b = new Button();
b.Text = c.ToString();
...
b.Click += new EventHandler (...);
Controls.Add(b);
}
 
Jon Skeet said:
I think that rather than generate the event handlers separately, I'd
just generate the buttons and the event handlers in one go:

for (char c = 'A'; c <= 'Z'; c++)
{
Button b = new Button();
b.Text = c.ToString();
...
b.Click += new EventHandler (...);
Controls.Add(b);
}
That depends on whether you want to use the designer to lay out the look of
the buttons. If you do, I think you have to let the designer define the
buttons (am I right?) Depending on how you want them to look, it might be
easier to generate them of course. But even if you do use the designer, you
don't have to attach the events through the designer. Rather than going to
26+ different controls and pulling up the right function definition from the
designer's list, you could do it in 6 lines of code, either late in the
constructor, or during a form_load or other such event. Of course, you could
probably select all the buttons, and only click once to attach them all, but
I like the loop because it will give the event to new buttons automatically
(and prevents you from accidentally missing one when you select them all.)

-Rachel
 
Rachel Suddeth said:
That depends on whether you want to use the designer to lay out the look of
the buttons. If you do, I think you have to let the designer define the
buttons (am I right?)

Yes, unfortunately I believe that's true.

However, if you've got 26 buttons, it's going to be very tedious to
create all the buttons in the designer, and you'll end up with hideous
code (26 member variables declared for no good reason, for instance -
and unless you rename them manually, they'll all have nasty names,
too).

Of course, you can design the rest of the form in the designer only
write the code to add the buttons.

Then again, I have a bit of a bias against the designer - I feel it
tends to generate code which has far more member variables than are
required, and isn't nice code to read or maintain. It makes things
quicker to start with at the expense of long term code maintainability.
 
Yes, in the form or class' constructor add the following

this.Button_Click+= new System.EventHandler(nameofmethod);
this.Button1_Click+= new System.EventHandler(nameofmethod);
this.Button2_Click+= new System.EventHandler(nameofmethod);
etc.

with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- http://www.411asp.net/func/search?
qry=Ravichandran+J.V.&cob=aspnetpro
- http://www.southasianoutlook.com
- http://www.MSDNAA.Net
- http://www.csharphelp.com
- http://www.poetry.com/Publications/
display.asp?ID=P3966388&BN=999&PN=2
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 
"Jon Skeet [C# MVP]" wrote in message
Yes, unfortunately I believe that's true.

However, if you've got 26 buttons, it's going to be very tedious to
create all the buttons in the designer, and you'll end up with hideous
code (26 member variables declared for no good reason, for instance -
and unless you rename them manually, they'll all have nasty names,
too). ...

This is true. And if you just wanted a nice neat grid full of buttons, it
would be so much easier to generate them. But what if you need them in an
order that's not easy to generate, in a layout where the locations aren't
easy to calculate (in this case, say you want them in qwerty layout?) What
if you have some buttons that you want to be a special size? Although
there's a lot about the designer that's tedious, it is easier than trying to
guess at sizes and locations, then running, then fixing, maybe 8 or 10 times
before it looks right... Then if you want to add another button (say tab
and shift) then you have to move everything over to make room for them, and
that means you have to change the location of all those other buttons you
previously calculated locations for by hand... that's messy. It is possible
to separate the code you're actually going to write from the designer code
(using regions, or by understanding where the designer puts code, and
avoiding mixing yours up there. Also, by putting as much of your code as
reasonable into separate classes or components - yes, so that you only use
the designer where it's actually helpful.) That way you (in theory) never
need to look at the ugly code the desiger makes... just look at the designer
results for that stuff.

What would be nice is if you could generate the buttons early in the
constructor, and then have the designer notice them, and draw them, and let
you change the sizes/locations that get set in InitializeComponent. That is
my fantasy :-)
 
Back
Top