Click here to Skip to main content
15,885,799 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I have a datagridview windows forms application using vb.net that restricts certain user input such as characters, special characters, punctuation and negative numbers. However when I restrict input such as this it also restricts the use of any numbers with decimal places. The "." symbol is always rejected. Is there anyway to reject "." unless its in combination with a numeric value? The code below is a short snippit of my validation check for non-numerical input, however it doesn't recognize numerical values with decimal places (i.e. ".") as being numerical. Is there anything I can do to avoid this issue?

VB
Dim value As String = DataGridView1.Rows(rowindex).Cells(columnindex).Value.ToString

                For Each c As Char In value
                    If Not Char.IsDigit(c) Then
                            MessageBox.Show("Not a Valid Entry")
                        Else
                        'Default value provided after validation
                        DataGridView1.Rows(rowindex).Cells(columnindex).Value = 0.5

                    End If
                Next
Posted

1 solution

Filtering out input of data in the DataGridViewCell is really easy. Unfortunately, you are not even trying to do it in your code. It's absolutely unclear how can your code work even for validation. It cannot.

So, let's start with filtering. First, you need to obtain the control to handle. The edit control is created each time you enter the editing mode. So, first, you need to handle the event DataGridView.EditingControlShowing. It will give you the reference to editing control through the event arguments parameter, its property Control. Please see:
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.editingcontrolshowing%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridvieweditingcontrolshowingeventargs%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridvieweditingcontrolshowingeventargs.control(v=vs.110).aspx[^].

After this is done, you obtain this control reference of the type Control. As with all controls, you can filter out some input characters by handling the event Control.KeyPress. This control is cancellable, you can avoid entering some character by assigning true to the properly Cancel of the event arguments parameter. This is explained here, pay attention for the code sample:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress%28v=vs.110%29.aspx[^].

In the simplest possible case, just for demonstration, let's assume you have to do it will all the cells of some instance of the grid:
C#
DataGridView myGridView = //...

//...

myGridView.EditingControlShowing += (sender, eventArgs) => {
    // here it's not too late to check some properties of myGridView 
    // or eventArgs and exit if you don't want to deal with the eventArgs.Control
    Control control = eventArgs.Control; // if the execution gets here, control is always created
    control.KeyPress += (keyPressSender, keyPressEventArgs => {
                       // pay attention: different parameter names
                       // are used, to avoid name conflict with outer-context
                       // "sender" and "eventArgs"
        keyPressEventArgs = !goodDoubleCharacter(keyPressEventArgs.KeyChar); // this is how filtering out is done        
    } //control.KeyPress
    // 
} //myGridView.EditingControlShowing

//...

static bool goodDoubleCharacter(char testCharacter) {
   return // ... the remaining problem is to decide which characters to allow to be entered in the above code
}

Simple, isn't it? Now you can allow decimal point, all digits, optionally + or −, optionally 'E' or 'e', for scientific notation, and, important, (char)8, which is the backspace, by some weird historical reason also processed as character and not as the virtual key, so it will be filtered out if you forget it.

Now, most important part of the answer: don't even try to to reject '.' unless its in combination with a numeric value"! You would only greatly confuse the user, create enormous inconveniences (let's say, drive the users crazy) and still won't be able to guarantee valid input. Criteria like this never make some sense. You should later just validate the input.

I'll explain. Let's say, you want to allow only one '.' and only between two integers. Now imagine how the user enters the value. The user enters one digit then, '.', then… wait a second! input is already invalid; there is not trailing character. Ah, you want to allow '.' at the end during input? But there is no "during input". The user can enter digits first, and only later insert '.', but a reasonable user won't do it. The users expect that they are allowed to enter some invalid string at first and make it valid only by the moment when the entered data is about to be used.

So, my advice would be: validate data only when the data is about to be used. Many validate data item by item, when a user shifts the control focus to other control (not applicable to a single grid view with editing cells). Even though in simple cases it can be useful, it general case this is simply impossible, because some elements of data may depend on each other, they are valid or not not separately, but all together, only. And this is applicable to a set of cells on a grid view, too.

So, how to validate? Of course, but by checking where '.' is. :-)

First, you need to check up if the string is valid as the representation of the floating-point value (for example, double). This is how:
C#
DataGridViewCell cell = // ... for some cell...
string value = (string)cell.Value;
double doubleValue;
bool valid = double.Parse(value, out doubleValue);
Note that you also obtained the double value, for free. You can use it for further validation, say, to validate that the value falls in some valid range.

Sorry that the code is in C#. I hope it is clear enough to give you the idea. In VB.NET, everything will be pretty much the same. I uses anonymous event handlers (highly recommended), and similar VB.NET syntax is explained here: http://visualstudiomagazine.com/articles/2011/11/28/integrating-lambda-expressions-and-events.aspx[^].

Anyway, you can consult appropriate MSDN pages on each type/method used.

—SA
 
Share this answer
 
v5

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