Make a specific column only accept numeric value in datagridview in Keypress event
Asked Answered
N

7

51

I need to make datagridview that only accept the numeric value for specific column only in keypress event. Is there any best way to do this?

Natheless answered 28/9, 2012 at 18:31 Comment(0)
M
81
  • Add an event of EditingControlShowing
  • In EditingControlShowing, check that if the current cell lies in the desired column.
  • Register a new event of KeyPress in EditingControlShowing(if above condition is true).
  • Remove any KeyPress event added previously in EditingControlShowing.
  • In KeyPress event, check that if key is not digit then cancel the input.

Example:

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    e.Control.KeyPress -= new KeyPressEventHandler(Column1_KeyPress);
    if (dataGridView1.CurrentCell.ColumnIndex == 0) //Desired Column
    {
        TextBox tb = e.Control as TextBox;
        if (tb != null)
        {
            tb.KeyPress += new KeyPressEventHandler(Column1_KeyPress);
        }
    }
}

private void Column1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
    {
        e.Handled = true;
    }
}
Maiocco answered 1/2, 2013 at 3:35 Comment(9)
I'm not criticizing this answer, but stating a general remark: Wouldn't it be nice to be able to set a formatter of some kind on a column with default formatters like AllowNumericOnly or so. Just like a property.Collin
Excellent answer! This keeps them from so much as typing invalid data. I would like to add though, that using a hard coded column index isn't a great idea. I would recommend using if( dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns["name"].Index )Sauropod
@druciferre Even better: dataGridView1.CurrentCell.ColumnIndex == dataGridView.Columns.IndexOf(dataGridViewColumn1);Lionel
@PontusMagnusson, couldn't you just use dataGridViewColumn1.ColumnIndex if you've defined a control for the column?Sauropod
Wow who knew? Although it's dgvc1.IndexLionel
is this event in asp.net?I'm not able to add EditingControlShowing.Bidden
WHAT IF I WANT NEGATIVE VALUES HERE. Just allowing '-' won't work because the user can place it anywhere for ex 123-23Fisticuffs
Good Answer, One thing to add here is that this does not prevent the user to paste from the context menu.Plot
Thanks for sharing this solution! That helped me!Contemplate
B
36

You must use DataGridView.CellValidating Event like this :

    private void dataGridView1_CellValidating(object sender, 
                                           DataGridViewCellValidatingEventArgs e)
    {
        if (e.ColumnIndex == 1) // 1 should be your column index
        {
            int i;

            if (!int.TryParse(Convert.ToString(e.FormattedValue), out i))
            {
                e.Cancel = true;
                label1.Text ="please enter numeric";
            }
            else
            {
                // the input is numeric 
            }
        }
    }
Bushwa answered 28/9, 2012 at 19:34 Comment(2)
can you add the code for allowing one decimal also in this event please?Inhabit
Excellent answer If anyone needs to allow decimal then just change "int.TryParse" to "decimal.TryParse"Tootle
M
10
 private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        e.Control.KeyPress -= new KeyPressEventHandler(Column1_KeyPress);
        if (dataGridView1.CurrentCell.ColumnIndex == 4) //Desired Column
        {
            TextBox tb = e.Control as TextBox;
            if (tb != null)
            {
                tb.KeyPress += new KeyPressEventHandler(Column1_KeyPress);
            }
        }

    }
    private void Column1_KeyPress(object sender, KeyPressEventArgs e)
    { 
          // allowed only numeric value  ex.10
        //if (!char.IsControl(e.KeyChar)
        //    && !char.IsDigit(e.KeyChar))
        //{
        //    e.Handled = true;
        //}

               // allowed numeric and one dot  ex. 10.23
        if (!char.IsControl(e.KeyChar)&& !char.IsDigit(e.KeyChar)
             && e.KeyChar != '.')
        {
            e.Handled = true;
        }

        // only allow one decimal point
        if (e.KeyChar == '.'
            && (sender as TextBox).Text.IndexOf('.') > -1)
        {
            e.Handled = true;
        }
    }
Misbecome answered 17/9, 2013 at 5:25 Comment(0)
M
4

The answer given is excellent unless you require decimal places as others have pointed out. In this event you need to extend the validation, add the using and vars below to get a culture variable value for the decimal separator

using System.Globalization;

NumberFormatInfo nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
char decSeperator;

decSeperator = nfi.CurrencyDecimalSeparator[0];

Extend the validation to:

if (!char.IsControl(e.KeyChar) && !(char.IsDigit(e.KeyChar) 
| e.KeyChar == decSeperator))
{
    e.Handled = true;
}
// only allow one decimal point
if (e.KeyChar == decSeperator
    && (sender as TextBox).Text.IndexOf(decSeperator) > -1)
{
    e.Handled = true;
}
Maury answered 12/10, 2015 at 11:48 Comment(2)
I like the extended validation. I noticed though that a decimal character was never accepted as a valid KeyChar because the KeyPressEventArgs returned true even on entering the first decimal in the textbox. I added else if (e.KeyChar == decSeparator) { e.Handled = false; } as part of the IndexOf condition. ThanksVacillate
Object reference not set to an instance of an object.Tumbler
C
3
Private WithEvents txtNumeric As New DataGridViewTextBoxEditingControl

Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing

txtNumeric = CType(e.Control, DataGridViewTextBoxEditingControl)
End Sub

Private Sub txtNumeric_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtNumeric.KeyPress
    If (DataGridView1.CurrentCell.ColumnIndex > 0) Then
        If (Not Char.IsControl(e.KeyChar) And Not Char.IsDigit(e.KeyChar) And Not e.KeyChar = ".") Then
            e.Handled = True
        Else
            'only allow one decimal point
            If (e.KeyChar = "." And txtNumeric.Text.Contains(".")) Then
                e.Handled = True
            End If
        End If
    End If
End Sub
Cahilly answered 17/8, 2015 at 11:27 Comment(1)
Format your answer properlyGobbledegook
T
0

You could also try this way, with accept decimals character

    private void Column1_KeyPress(object sender, KeyPressEventArgs e) 
    {
        //allow number, backspace and dot
        if (!(char.IsDigit(e.KeyChar) || e.KeyChar == (char)Keys.Back || e.KeyChar == '.'))
        {
            e.Handled = true;

        }
        //allow only one dot
        if (e.KeyChar == '.' && (sender as TextBox).Text.Contains("."))
        {
            e.Handled = true;

        }
    }
Thies answered 18/5, 2019 at 5:33 Comment(0)
U
0

I was doing a matrix calculator and was using two DataGridView objects. Here's a code that worked for me. I took the very first comment from this post and changed it a bit.

//Adding characters to a cell
    private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        
            if (e.Control != null)
            {
                e.Control.KeyPress += new KeyPressEventHandler(Column1_KeyPress);
                Console.WriteLine(e.Control.Text);
            }
    }
    //Handling presses for minus dot and numbers
    private void Column1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '-' && e.KeyChar != '.')
            e.Handled = true;
        if (e.KeyChar == '.')
        {
            if (((DataGridViewTextBoxEditingControl)sender).Text.Length == 0)
                e.Handled = true;
            if (((DataGridViewTextBoxEditingControl)sender).Text.Contains('.'))
                e.Handled = true;
        }
        if (e.KeyChar == '-')
        {
            if (((DataGridViewTextBoxEditingControl)sender).Text.Length != 0)
                e.Handled = true;
            if (((DataGridViewTextBoxEditingControl)sender).Text.Contains('-'))
                e.Handled = true;
        }
    }
Unknowing answered 19/12, 2021 at 22:10 Comment(2)
Welcome to StackOverflow. Could you please translate your comments to English inside the code block?Redfish
Sorry for taking so long, I don't visit this site often.Unknowing

© 2022 - 2024 — McMap. All rights reserved.