【问题标题】:Make a specific column only accept numeric value in datagridview in Keypress event在 Keypress 事件中使特定列仅接受 datagridview 中的数值
【发布时间】:2012-09-28 18:31:00
【问题描述】:

我需要制作仅在按键事件中仅接受特定列的数值的 datagridview。有没有最好的方法来做到这一点?

【问题讨论】:

    标签: c# datagridview keypress


    【解决方案1】:
    • 添加 EditingControlShowing 事件
    • 在 EditingControlShowing 中,检查当前单元格是否位于所需的列中。
    • 在EditingControlShowing中注册一个新的KeyPress事件(如果以上条件为真)。
    • 删除之前在 EditingControlShowing 中添加的所有 KeyPress 事件。
    • 在 KeyPress 事件中,检查如果键不是数字则取消输入。

    例子:

    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;
        }
    }
    

    【讨论】:

    • 我不是在批评这个答案,而是说一个一般性的评论:能够在具有默认格式化程序(如 AllowNumericOnly 左右)的列上设置某种格式化程序不是很好吗.就像一个属性。
    • 优秀的答案!这可以防止他们输入无效数据。不过,我想补充一点,使用硬编码的列索引并不是一个好主意。我建议使用if( dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns["name"].Index )
    • @druciferre 更好:dataGridView1.CurrentCell.ColumnIndex == dataGridView.Columns.IndexOf(dataGridViewColumn1);
    • @PontusMagnusson,如果您已经为列定义了控件,您不能只使用dataGridViewColumn1.ColumnIndex吗?
    • 好答案,这里要添加的一件事是,这不会阻止用户从上下文菜单中粘贴。
    【解决方案2】:

    你必须像这样使用DataGridView.CellValidating Event

        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 
                }
            }
        }
    

    【讨论】:

    • 能否在这个事件中添加允许一位小数的代码?
    • 优秀的答案如果有人需要允许小数,那么只需将“int.TryParse”更改为“decimal.TryParse”
    【解决方案3】:
     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;
            }
        }
    

    【讨论】:

      【解决方案4】:

      除非您像其他人指出的那样需要小数位,否则给出的答案非常好。 在这种情况下,您需要扩展验证,在下面添加 using 和 vars 以获得小数分隔符的区域性变量值

      using System.Globalization;
      
      NumberFormatInfo nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
      char decSeperator;
      
      decSeperator = nfi.CurrencyDecimalSeparator[0];
      

      将验证扩展到:

      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;
      }
      

      【讨论】:

      • 我喜欢扩展验证。我注意到尽管十进制字符从未被接受为有效的 KeyChar,因为即使在文本框中输入第一个小数时 KeyPressEventArgs 也会返回 true。我添加了 else if (e.KeyChar == decSeparator) { e.Handled = false; } 作为 IndexOf 条件的一部分。谢谢
      • 对象引用未设置为对象的实例。
      【解决方案5】:
      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
      

      【讨论】:

      • 正确格式化您的答案
      【解决方案6】:

      您也可以尝试这种方式,接受小数字符

          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;
      
              }
          }
      

      【讨论】:

        【解决方案7】:

        我正在做一个矩阵计算器并使用两个 DataGridView 对象。这是一个对我有用的代码。我从这篇文章中获取了第一条评论并对其进行了一些修改。

        //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;
                }
            }
        

        【讨论】:

        • 欢迎来到 StackOverflow。您能否在代码块中将您的 cmets 翻译成英文?
        • 抱歉拖了这么久,我不经常访问这个网站。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-17
        • 1970-01-01
        • 1970-01-01
        • 2016-08-09
        • 1970-01-01
        相关资源
        最近更新 更多