Click here to Skip to main content
15,886,519 members
Please Sign up or sign in to vote.
2.76/5 (5 votes)
See more:
i have a form which include 30 or 40 texboxes i want to validate it that user enter only number in text box not characters. so i have made a method which will be called on textbox key press event but the question it is possible to call this one method on every keypress event of textbox how can i assign this method to all textbox's keypress event?
Posted
Comments
Sergey Alexandrovich Kryukov 22-Oct-14 3:29am    
This time, you asked a valid reasonable question. My congratulations and vote of 5 (despite one problem of terminology and understanding of events, "assign"). Another problem is 30-40 text boxes, which could be a sign of poor UI design.

Amazingly, so far, my Solution 4 is the only one answering your question.

—SA
Muhamad Faizan Khan 22-Oct-14 12:03pm    
textboxes are on three different tabs as well. by the way it is the requirement so how can be poor ui design

First, if you select, at design-time, all the TextBoxes you wish to assign the same EventHandler to for a specific event, and then open the Property Inspector (F4), you can select an EventHandler you have defined, and it will be wired-up to (added to the invocation list) all the selected TextBoxes. Or, as you have seen, in the other solutions here, you can add the EventHandler in code.

Here's a code example of a KeyPress EventHandler for TextBox, for constraining text input from the keyboard I've used in the past; it will ignore keyboard combinations like Control-V (paste):
C#
private const char chrDelete = (char) Keys.Delete;

private const char chrBackSpace = (char) Keys.Back;

private const char chrEnterReturn = (char)Keys.Enter;

private void DigitsOnlyTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
    char currentKey = e.KeyChar;

    e.Handled = ! (Char.IsDigit(currentKey) || currentKey == chrDelete || currentKey == chrBackSpace || currentKey == chrEnterReturn);

    if (e.Handled) return;

    if (currentKey == chrEnterReturn)
    {
        // call code to handle Enter/Return Event
    }
}
To prevent the right-click Context Menu from appearing set the 'ShortcutsEnabled property of the TextBox to 'false: that's the "cheap" way to block the user pasting whatever into the TextBox.

To allow pasting, but intercept the paste event and validate it ... make sure it's all digits ... is complicated in WinForms, but can be done.
 
Share this answer
 
v3
Use MaskedTextBox with appropriate mask (you'll have to lookup number representations).

Another way to do this is to create your own control (NumericTextBox?) in which you will do all validation and keypress handling. Then you simply put your NumericTextBox instead of "normal" one.



There is no easier way. If you really want to handle each one as per your question you can have one handler function for every control, but you still have to attach the event.

You can do for each loop on controls collection of the form and for each TextBox add the event...but you'll run into trouble first time you need textbox that is NOT numeric.

If this solution helps, please take time to accept the solution. Thank you.
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 22-Oct-14 3:24am    
This can be a good idea to use MaskedTextBox, but, in many cases, one would need exactly what OP requested: filter out everything except digits (and backspace). And you did not answer to this valid request. Please see Solution 4.
—SA
Sinisa Hajnal 22-Oct-14 3:44am    
Read my solution again, last one answers his question. I just wrote suggestions first. I would create my own TextBox extension or inherited control.
Sergey Alexandrovich Kryukov 22-Oct-14 3:55am    
There is no a need to inherit this control (and I don't know what's "extension").
"Run into trouble" is just false statement. OP can add a handler to any set of controls, not all of them. Also, attach an event is the wrong concept. Again, event handling is done by: adding a handler to the invocation list of the event instance using += operator. There is no such thing as "attach event".

As to answering OP's question: where? you simply repeated what OP said, in other words. OP knows that he handles the event, all essence is in some detail.

So, your comment only helped me to see that you answer is even worse than I thought in first place.

—SA
Sinisa Hajnal 22-Oct-14 4:10am    
He said "assign this method to all textbox's keypress event?" note ALL textboxes...therefore I described looping through all forms controls and finding textboxes. He would run into trouble with such implementation only if he gets some that shouldn't be numeric.

I don't see how is that any different from your solution except you're using some created control collection.

As for attaching events - too much jQuery :( I use more VB.NET and use AddHandler keyword regularly. I just work on the web project right now :)

Extension: http://msdn.microsoft.com/en-us/library/bb383977.aspx

I don't intend to comment any more on this, I don't have to defend my solution to you, but to Mr. Khan. Your solution has its drawbacks too, but it is valid solution nevertheless. You don't seem to mind those.
Sergey Alexandrovich Kryukov 22-Oct-14 10:12am    
You referenced method extension, but in your comment you said: TextBox extension. So, wasn't that the idea on something which does not exist? :-)

—SA
It's not "assign". If you have an event instance, you can add an event handler to its invocation list, using the operator '+='. For example:
C#
using System.Windows.Forms;

// ...

    void AddEventHandlers(TextBox[] allMyTextBoxes) {
        foreach (TextBox textBox in allMyTextBoxes)
            textBox.KeyPress += (sender, eventArgs) => {
                TextBox instance = (TextBox)sender; // in case you need to
                                                    // identify them
                char keyChar = eventArgs.KeyChar; // to know what's pressed :-)
                // if you want to cancel some key press, use:
                // eventArgs.Handled = true;
                // in your case:
                if (!(keyChar == (char)8) || char.IsDigit(keyChar))
                    eventArgs.Handled = true;
                // and so on... generally, do whatever you want:
                //DoSomethingWithEventThoseParameters(sender, keyChar);
                // or
                //DoSomethingElseWithEventArguments(eventArgs);
                // ...
            };
    }

Important: note that I also allowed a character #8. This is backspace. Don't forget about it when filtering input.

Please see:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.keypresseventargs.handled%28v=vs.110%29.aspx[^].

Note that if you want to deal not with characters, but with keys, you need to handle the events KeyDown or KeyUp.

—SA
 
Share this answer
 
v4
Comments
Sinisa Hajnal 22-Oct-14 4:15am    
@Khan: You'll need extra logic for maintaining the collection of textboxes. Also, be aware that keypress validation will not prevent copy/pasting, you still have to have validation before saving the data.

@Sergey: You provide code so more stars to you :)
Sergey Alexandrovich Kryukov 22-Oct-14 10:09am    
It's not "extra" :-)
This logic would be quite trivial. We don't have any logic from OP for selection of this set, so it would be the best to leave it as is.
Good point about Paste. Thank you.
—SA
BillWoodruff 22-Oct-14 11:51am    
#1 I have to vote this solution one because I am sure this was posted by someone who is not the real Sergey Alexandrovich Kryukov.

The real Sergey Alexandrovich Kryukov is a meticulous craftsman/philosopher of C# programming. He would never write code that someone, like myself, could easily see would never compile: ranging from 'for instead of 'foreach to 'IsDigit rather than 'Char.IsDigit, and the lack of the lambda assignment operator => in the Event += code.
Sergey Alexandrovich Kryukov 22-Oct-14 13:04pm    
Thank you very much, Bill.

Quite apparently, in a little rush, I've over-estimated my own confidence, or demonstrated some false confidence.
Fixed. (There were some more bugs.) I also remembered my own, better technique of answering with a code sample, avoiding uncertain lines which won't compile, such as TextBox[] = //..., by abstracting them out using a function (isn't it a good idea?).

By the way, I could not even imagine that someone could blame me in doing something bad not only quite fairly, but also in such a flattering (and, I would say, kind of elegant) way. :-)
Anyway, I would say my thank you even it was "What's the hell is that non-compiling code?", just because this is what it was. :-)

—SA
That's an easy one i think. You have to link to that event handler in all your textboxes. Something like this:

C#
this.textbox1.KeyPress += new KeyPressEventHandler(textboxes_KeyPress);
this.textbox2.KeyPress += new KeyPressEventHandler(textboxes_KeyPress);


And then:

C#
void textboxes_KeyPress(object sender, KeyPressEventArgs e)
{
    //call your common method
}


EDIT:

As Sinisa points out,if you have a lot you must do something like this:
C#
foreach(Control c in Form1) //this must be the container of the textboxes,(form,panel,groupbox)
{
if (c is TextBox)
   {
     c.KeyPress += new KeyPressEventHandler(textboxes_KeyPress);
   }
}
 
Share this answer
 
v2
Comments
Sinisa Hajnal 22-Oct-14 3:45am    
And what happens when he has 20 or more of these?
Pikoh 22-Oct-14 4:56am    
See updated solution

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900