3
votes

I have a DataGridView which I bind to a DataTable, through a BindingSource. Simple example code.

DataTable records;
BindingSource bindRecords;

private void InitGrid() {
    records = new DataTable();
    records.Columns.Add(new DataColumn("text", typeof(string)));

    bindRecords = new BindingSource();
    bindRecords.DataSource = records;

    dgvRecords.DataSource = bindRecords;
}

Then I use the CellValidating event like this:

private void dgvRecords_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
    if(e.ColumnIndex == dgvRecords.Columns["text"].Index) {
        if(e.FormattedValue.ToString() == "error") {
            dgvRecords[e.ColumnIndex, e.RowIndex].ErrorText = "Oops!";
        }
    }
}

Now when user inputs as text the literal "error", an error icon is shown in the cell. So far so good.

But if I sort the column the validation is lost. I understand that in order for the cell validating event to fire the cell must be entered and then leaved.

I also have the same problem when inserting data programmatically like this:

private void btnAddRecord_Click(object sender, EventArgs e) {
    records.Rows.Add(new object[] { "error" });
}

How would I force validation to occur? I don't want hacks like traversing the grid and setting the CurrentCell.

1

1 Answers

1
votes

Your problem is that the CellValidating event only seems to happen when you exit the cell (i.e. finish editing). Therefore, I tested and found that putting the code you specified into another event that fires after a sort, like CellPainting, accomplishes what you wish. For example:

    private void dgvRecords_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        if (e.ColumnIndex == dgvRecords.Columns["text"].Index)
        {
            if (e.FormattedValue.ToString() == "error")
            {
                dgvRecords[e.ColumnIndex, e.RowIndex].ErrorText = "Oops!";
            }
        }
    }