break

Bug: DataGridViewCell adding itself

If you run the code below you will notice the following behavior:

For some reason when I press a button and the button puts an error text in my cell (because of an error validation) when I go back to the cell, it selects all the text in the datagridviewcell and if you press a number you are going to be able to watch two behaviors:

1- The Datagridviewcell adds itself:
This was happening in my real world application.
For example, if I have a number like 1111.000 (let’s say this sends a validation error), if you go back to the cell and press “1″ you will see something like
1111.001
If you press “5″ you will see something like
1111.002
If you keep pressing numbers you will see that you will be adding your current number.

2- The Datagridviewcell will only let you put one number at a time.
This is what happens in the code below. If you press 1111.000 and you go back to the cell and press “1″ you will see something like
1.000

If you press “2″ instead of being 12.000 or 1.002 you will see
2.000

It will only let you put one number at a time.

Here’s the code for this scenario


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace DataGridViewBugBlog
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
InitializeGridColumns();
FormatDataGridColumn(dataGridView1, "Price", typeof(double), null);
}
private void InitializeGridColumns()
{
DataSet ds = new DataSet();
DataTable dt = new DataTable();
ds.Tables.AddRange(new System.Data.DataTable[] {dt});
// Adding columns to the DataTable
dt.Columns.Add("Quantity", typeof(double));
dt.Columns.Add("Price", typeof(double));
dataGridView1.DataSource = ds.Tables[0].DefaultView;
// Setting the width of both columns
foreach (DataGridViewColumn col in dataGridView1.Columns)
col.Width = 95;
}
private void button1_Click(object sender, EventArgs e)
{
showConfirmation();
}
///


/// If the price or quantity doesn’t have a correct
/// format it will send a messagebox.
///

private void showConfirmation()
{
bool error = false;
foreach (DataGridViewRow mRow in this.dataGridView1.Rows)
if (!ValidateData(mRow))
error = true;
if (error)
MessageBox.Show(”Invalid quantity or price, please check and reenter”, “Errors”, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
///
/// The valid format for the price
/// is 000,0000
///

private bool ValidateData(DataGridViewRow mRow)
{
bool ok = true;
string txtPrice = “Price”;
//quantity format
if (!Regex.IsMatch(mRow.Cells[txtPrice].FormattedValue.
ToString(), @”(?!^0*$)(?!^0*\.0*$)^\d{1,3}(\.\d{1,4})?$”))
mRow.Cells[txtPrice].ErrorText = “Please enter a valid numeric format. Ex (000,0000) “;
ok = false;
return ok;
}
///
/// This event handler manually raises the CellValueChanged event
/// by calling the CommitEdit method. The event CellValueChanged
/// was used to handle DataGridViewCheckBoxCell logic.
///

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty && dataGridView1.CurrentCell.ColumnIndex >= dataGridView1.Columns[”Price”].Index)
dataGridView1.
CommitEdit(DataGridViewDataErrorContexts.Commit);
}
internal static void FormatDataGridColumn(DataGridView dataGrid, string col, Type type,
string format)
{
DataGridViewColumn column = dataGrid.Columns[col];
if (type == typeof(Double))
column.DefaultCellStyle.Format = format == null ? “##0.0000″ : format;
}
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
}
}
}

This only an excerpt of my code. The interesting part about this, is that what causes this error is the CurrentCellDirtyStateChanged event. I had this event because inside of it i had a CommitEdit method that raises the CellValueChanged event in which I was changing the values of some DataGridViewCheckBoxCell.

The solution:
Make sure in the CurrentCellDirtyStateChanged the CommitEdit is only made when you are in a DataGridViewCheckBoxCell. For the code above just comment the CommitEdit method and it will work like it should.

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.