views:

701

answers:

3

I have a client having a problem with a DataGridView in a Windows app. They are calling the CellValidated event, but they want to have different validation for the cell if it is in a row that is already committed back to the datasource than if it is a row that is first being added (and not yet committed (the user hasn't left the row yet). I tried the IsNewRow property, but as soon as you start typing in the row, another "new row" is added, so the row you are working with is no longer considered the new row. I know the row has not been committed yet because you can hit Esc to cancel editing, and the entire row goes away.

Is there a way to tell if the currently edited row is actually the "new row" in the sense that it hasn't been committed back to the datasource?

+2  A: 

One way I've achieved something similar in the past is to utilise the id property of my objects that are bound to the list.

For example, if I have a BindingList<User> where user is something like:

public class Names
{
    public string Name { get; set; }         
    public int id { get; set; }
}

I can then bind my list like this:

dataGridView1.AutoGenerateColumns = false;
_users = new BindingList<User>();
_users .Add(new Names() { Name = "joe", id=1 });
_users .Add(new Names() { Name = "pete", id = 2 });

bindingSource1.DataSource = _names;

DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
col1.DataPropertyName = "Name";        

dataGridView1.Columns.Add(col1);

dataGridView1.DataSource = _users;

Then, when the DataGridView provides a new row, it will have an id of 0 (the default value for an integer).

Every object that comes from the database has a non zero id.

There may also be a way to achieve this using BindingSources but I had a quick look over the properties there and nothing leaped out at me.

David Hall
I like this answer, and it seems like it would work, but since I'm working with a generic dataset, not a collection of objects, I can't verify it completely in this case. I'm voting it up because it could provide useful in different situations, just not in this one unfortunately.
Charles Boyung
+3  A: 

What is the data source in this case?

If it's a datatable, then you can easily test the DataRowState property of the datatable's rows to see if they are new or existing. Once you've validated your datarows, you can then call an Accept on the table to commit those rows. There is no need to interfere between the grid and it's datatable, in this situation.

Of course, this doesn't mean your data is actually committed to a database, if that's where it's finally stored. That would be another step.

Also, I usually avoid directly writing to a datagridview; instead, I make it read-only and pop up an add/entry screen which can perform any validation required.

I don't know if any of this has been of use to you - if I've missed the point please let me know.

GenericMeatUnit
This doesn't work because when a row is being added and you haven't left the row yet, it doesn't exist in the data table yet. Trying to access the row at the RowIndex for the row throws an exception. However, this did help me find a way to make this work - checking that the row exists in the dataset
Charles Boyung
Nice answer - welcome to StackOverflow!
David Hall
A: 

GenericMeatUnit's answer didn't work for me, but it provided me with enough to find a way to make it work. Here's how I am doing the check now:

if (this.DATASET.DATATABLE.Rows.Count == e.RowIndex)

This if statement works because before leaving the row in the DataGridView, it doesn't actually exist in the datatable yet, so the number of rows in the datatable will be equal to the RowIndex for the new row, since RowIndex is zero-based.

Charles Boyung