views:

2149

answers:

8

I have an event handler for a Textbox as well as for a RichTextBox. The code is identical, but

In handler #1 i do:

RichTextBox tb = (RichTextBox)sender

In handler #2 accordingly:

TextBox tb = (TextBox)sender

Doing so i can fully manipulate the sending control. What i want to know is how can i cast the sending object to Textbox or RichTextbox according to its type using

sender.GetType().Name

and then create the control at runtime and work with it. That way i only need one event handler function: less code, less errors, easier to maintain and DRY :-)

+2  A: 
RichTextBox textbox = sender as RichTextBox;
if (textbox != null)
{
   // do stuff as a rtb
   textbox.Text = "I'm a rtb";
   return;
}

TextBox textbox = sender as TextBox;
if (textbox != null)
{
   // do stuff as a textbox
   textbox.Text = "I'm a textbox";
}
Chris S
A: 

Rather than the type name you could use 'is':

if (sender is RichTextBox)
{
...
}
else if (sender is TextBox)
{
...
}
Stuart Dunkeld
that seems to be the best compromise - thanks
tfl
This is ok but @Chris suggestion is better. Since your going to do something with the objects immediately it will save you an extra cast.
Peter Lillevold
+2  A: 

Casting can only be done at compile-time and thus you need to know the types that you wish to cast to at compile-time. A runtime Type (as returned by GetType()) can therefore not be used when casting.

If it is polymorphism you are looking for you could access the Name property through reflection. I wouldn't go that way though just to be able to reuse event handlers.

If you want strong typing, a common base class or interface on the two senders is the only way to go.

Peter Lillevold
A: 

You never have to cast. I used to think the same way when I started, this 'pattern' is incorrect, and not really logical.

Your best bet is to use something like:

if (sender is TextBox)
{
  TextBox tb = (TextBox)sender;
}
else if (sender is RichTextBox)
{
  RichTextBox rtb = (RichTextBox)sender;
}
else
{
  // etc
}
leppie
A: 

If the code is identical, do you need to care? I wonder if casting to Control wouldn't give you everything you need...

One complex handler is not necessarily better than several simple handlers. Either way, if you have to go this route, "as"/"is" is preferable (it isn't dependent on strings etc):

TextBox tb = sender as TextBox;
if(tb!=null) {/* TextBox specific code */}
...
Marc Gravell
+1  A: 

Depending on what properties you need, you could cast the sender as a TextBoxBase as both the TextBox and RichTextBox both inherit from that sub-class.

Kieron
that looks promising! I'll give it a try...
tfl
Hope it works out (:
Kieron
A: 

if you dont want to repeat the code then you can cast both the controls, refactor the common actions to a separate method which takes TextBoxBase as an argument. And in your event handlers convert the controls to System.Windows.Forms.TextBoxBase as both controls are derived from the TexbBoxBase and call the method.

Please note If you need specific properties of any of these controls then this refactoring wont work.

gk
A: 

thanks to all!

tfl