Should I Subclass TextBox ?

  • Thread starter Thread starter Phill
  • Start date Start date
P

Phill

I'd like to have textboxes that only allow certain types of data. Like
only integers, decimals, etc.

Is it better to subclass TextBox for each type or to create only one
new TextBox class that has a property or method that makes it act
approprietly?

Making multiple objects seems like it would be easier to use at design
time but I don't know if it's kind of inefficient to have so many
classes that could be combined.
 
Hi Phill,

What do you mean by subclassing? Do you mean 'inheriting' or you do mean
subclassing in the old API fashion?

If you mean inheriting I don't thing it would make using the text box easier
during design time. Unless you don't provide your own designer you cannot
use the visual designer.

Anyways. the .NET way to filter keystrokes is to handle KeyPress event. You
can create custom control that host an edit box and do the filtering there.
Then you can add some properties to customize that user control's keystroke
filter. This is the easiest way to use the visual designer
 
But it seems to me there's no need to use the visual designer in order to
provide format-specific functionality (such as ensuring input are
numerical.) If you inherit from the TextBox control, then whenever you place
the derived control on a form (use the derived control in future
programming), you will get all the designer support that comes with the
TextBox control. Furthermore, it you add a special property (maybe something
FormatString), and it is something basic like a string, you will be able to
edit that property from the visual designer when using the control, without
having to add any designer code.

-Rachel

Stoitcho Goutsev (100) said:
Hi Phill,

What do you mean by subclassing? Do you mean 'inheriting' or you do mean
subclassing in the old API fashion?

If you mean inheriting I don't thing it would make using the text box
easier during design time. Unless you don't provide your own designer you
cannot use the visual designer.

Anyways. the .NET way to filter keystrokes is to handle KeyPress event.
You can create custom control that host an edit box and do the filtering
there. Then you can add some properties to customize that user control's
keystroke filter. This is the easiest way to use the visual designer


--
HTH
Stoitcho Goutsev (100) [C# MVP]


Phill said:
I'd like to have textboxes that only allow certain types of data. Like
only integers, decimals, etc.

Is it better to subclass TextBox for each type or to create only one
new TextBox class that has a property or method that makes it act
approprietly?

Making multiple objects seems like it would be easier to use at design
time but I don't know if it's kind of inefficient to have so many
classes that could be combined.
 
Phill said:
I'd like to have textboxes that only allow certain types of data. Like
only integers, decimals, etc.

Have you looked at System.Windows.Forms.NumericUpDown?
 
Hi Rachel,

If you inherit from the TextBox control, then whenever you place
the derived control on a form

There is the catch. You can not place it in the form. You can only create it
dynamically, which means it won't appear at design time. Unless. as I said,
you don't do your own designer.
Furthermore, it you add a special property (maybe something FormatString),
and it is something basic like a string, you will be able to edit that
property from the visual designer when using the control, without having
to add any designer code.

Completely correct if you could (but you can't) put it on the form.
 
Sure you can. I've done it. You start by creating a class library for the
new control. Any kind of project that will compile to a DLL will do. Then
you write your control class, eg:
-----
using System;
using System.Data;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace TextBoxTest
{
public class MyTextBox : System.Windows.Forms.TextBox
{
public string tp = "";
public MyTextBox(){}
public string TestProperty{ get{return tp;} set{tp = value;} }
}
}
------
(I probably don't need all those "usings", but...)

Now compile that. Create an executable project with a form. Add a reference
to the library you just created. Go to tool box, right-click/Add
Items/Browse, find the DLL for your library project. The new control will
appear in the tool box and you can put it on your form. You can set the
TestProperty or any other TextBox properties in the designer. You can mess
with them in code. It all works.

-Rachel
 
Rachel,
Yes, you are right. The only downsite is that there is a need of separate
project for that controls (separate assembly) and the other problem is that
the toolbox caches the controls and it could be bad experience when change
the source of the control.
But, yes it can be done this way.
 
Do you really avoid these problems by using a composite control in a single
project with your executable? If so, and your ap is actually small enough
you have no need for separately compiled modules, that would be the way to
go. Keep things as simple as possible. (Can you just expose the whole
TextBox as a public property? When we use composite controls, we expose only
the properties we actually use, one at a time, which is a good bit of work
up front but we think worth it.)

My own experience is that we do have a need to put things in modules to make
patch sizes reasonable. And we are using enough different custom controls
that it is worth having them in a library. In fact, we keep them in a
separate solution. This reminds us to completely close main project before
working on controls, and completely close controls project after making
changes & doing basic sanity testing on them (there is a small test project
in the controls library solution that doesn't compile on a release build.)
You avoid caching issues by completely closing, reopening after making
changes to controls. In a product of large scope, you won't be making a lot
of changes to the library by the time you get very far into the main
project.

-Rachel

Stoitcho Goutsev (100) said:
Rachel,
Yes, you are right. The only downsite is that there is a need of separate
project for that controls (separate assembly) and the other problem is
that the toolbox caches the controls and it could be bad experience when
change the source of the control.
But, yes it can be done this way.

--

Stoitcho Goutsev (100) [C# MVP]


Rachel Suddeth said:
Sure you can. I've done it. You start by creating a class library for the
new control. Any kind of project that will compile to a DLL will do. Then
you write your control class, eg:
-----
using System;
using System.Data;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace TextBoxTest
{
public class MyTextBox : System.Windows.Forms.TextBox
{
public string tp = "";
public MyTextBox(){}
public string TestProperty{ get{return tp;} set{tp = value;} }
}
}
------
(I probably don't need all those "usings", but...)

Now compile that. Create an executable project with a form. Add a
reference to the library you just created. Go to tool box,
right-click/Add Items/Browse, find the DLL for your library project. The
new control will appear in the tool box and you can put it on your form.
You can set the TestProperty or any other TextBox properties in the
designer. You can mess with them in code. It all works.

-Rachel
 
Rachel,

Well, all you said is right. Speeking in general for fairly complex controls
I couldn't agree more with you. But if we go back to the subject of this
thread, having separate assembly, not to speek of separate solution, for a
text box that filters keystrokes..... Well, I'd say that is too much. If I
were the original poster I wouldn't even bother to make user controls rather
I'd go with hooking on KeyPress event and do the filtering there.

Yes, I believe keeping things as simple as it possible is the way to go.

And finally whether to go with control on a separate project or solution
depends not on the size of the project, but on the complexity of the control
itself. The control, subject of this discution, I believe, is rather simple.
My practice shows that when one goes augment one of the stock controls that
augmentation is fairly simple. Otherwise one ends up with some really ugly
patches and hacks.


--

Stoitcho Goutsev (100) [C# MVP]


Rachel Suddeth said:
Do you really avoid these problems by using a composite control in a
single project with your executable? If so, and your ap is actually small
enough you have no need for separately compiled modules, that would be the
way to go. Keep things as simple as possible. (Can you just expose the
whole TextBox as a public property? When we use composite controls, we
expose only the properties we actually use, one at a time, which is a good
bit of work up front but we think worth it.)

My own experience is that we do have a need to put things in modules to
make patch sizes reasonable. And we are using enough different custom
controls that it is worth having them in a library. In fact, we keep them
in a separate solution. This reminds us to completely close main project
before working on controls, and completely close controls project after
making changes & doing basic sanity testing on them (there is a small test
project in the controls library solution that doesn't compile on a release
build.) You avoid caching issues by completely closing, reopening after
making changes to controls. In a product of large scope, you won't be
making a lot of changes to the library by the time you get very far into
the main project.

-Rachel

Stoitcho Goutsev (100) said:
Rachel,
Yes, you are right. The only downsite is that there is a need of separate
project for that controls (separate assembly) and the other problem is
that the toolbox caches the controls and it could be bad experience when
change the source of the control.
But, yes it can be done this way.

--

Stoitcho Goutsev (100) [C# MVP]


Rachel Suddeth said:
Sure you can. I've done it. You start by creating a class library for
the new control. Any kind of project that will compile to a DLL will do.
Then you write your control class, eg:
-----
using System;
using System.Data;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace TextBoxTest
{
public class MyTextBox : System.Windows.Forms.TextBox
{
public string tp = "";
public MyTextBox(){}
public string TestProperty{ get{return tp;} set{tp = value;} }
}
}
------
(I probably don't need all those "usings", but...)

Now compile that. Create an executable project with a form. Add a
reference to the library you just created. Go to tool box,
right-click/Add Items/Browse, find the DLL for your library project. The
new control will appear in the tool box and you can put it on your form.
You can set the TestProperty or any other TextBox properties in the
designer. You can mess with them in code. It all works.

-Rachel


Hi Rachel,

If you inherit from the TextBox control, then whenever you place
the derived control on a form

There is the catch. You can not place it in the form. You can only
create it dynamically, which means it won't appear at design time.
Unless. as I said, you don't do your own designer.

Furthermore, it you add a special property (maybe something
FormatString), and it is something basic like a string, you will be
able to edit that property from the visual designer when using the
control, without having to add any designer code.

Completely correct if you could (but you can't) put it on the form.
 
Stoitcho Goutsev (100) said:
But if we go back to the subject of this
thread, having separate assembly, not to speek of separate solution, for a
text box that filters keystrokes.....

Actually, you don't need a separate assembly (tested in VS.NET 2003). Just
bring up the dialog that allows you to add or remove items to the toolbox,
click 'Browse' and select your project's assembly.
 
Thanks for playing :-)
If I were only going to have a few forms, and wanted to do no more than was
asked about here, you are right I would not even be thinking about custom
controls. I guess my experience was coloring my view of the question... I
saw it as an example of the kind of thing one would want to do with a
TextBox, if not more than why worry about subclassing?

I meant to say that my experience has been that customers do not want to
wait for you to mail them a CD when they need an update. So if your
application is large, it is not practicable to have it all in one
executable. You need to be able to distribute fixes as reasonably-sized dlls
(or equivalent), so you can distribute it via immediate electronic transfer,
which means you'll be using more than 1 project anyway. In an application
the size I'm talking about, you will probably need dozens of numeric text
boxes, and dozens more boxes that take only caps, and a special button
attached to your datepickers, and you will want to have some other special
thing that's common to all your data entry fields that your customers have
come to expect uniformly across your application, etc... A large
application will (a) need to have more than 1 project anyway, and (b) be
more likely to call for a complex library, and (c) even for simple things I
don't want to have to remember to hook the event to 100 controls on 30
different forms -- i'm sure to miss a couple places. All those things are
related to the size of the ap.

-Rachel
 
Thanks, glad to know that. I thought I'd done that sort of thing in the
past, but didn't even know if it'd still work. I swear that when I first
started playing with C#, I could add a UserControl, go to the code and
change the :UserControl to :Button (for example), go back to the design
surface and there would be my button and I could use everthing in the
designer, but a couple weeks later I went back and that didn't work anymore.
I swear it did before, though, it really really did!
 
Rachel Suddeth said:
I swear that when I first
started playing with C#, I could add a UserControl, go to the code and
change the :UserControl to :Button (for example), go back to the design
surface and there would be my button and I could use everthing in the
designer, but a couple weeks later I went back and that didn't work anymore.
I swear it did before, though, it really really did!

Interesting. Just tried that here, and it works.
 
Yes, I'm impressed. I pretty sure I've tried out this before and it didn't
work.
The toolbox event handles changes made in the source. It looks like this has
been fixed somehow :)
 
Back
Top