C#DataGridView添加一行-验证时,如何知道该行是新的且尚未提交?

C#DataGridView添加一行-验证时,如何知道该行是新的且尚未提交?,c#,winforms,datagridview,C#,Winforms,Datagridview,我有一个客户端在Windows应用程序中的DataGridView出现问题。他们正在调用CellValidated事件,但如果单元格位于已提交回数据源的行中,他们希望对单元格进行不同的验证,而不是第一次添加(但尚未提交)的行(用户尚未离开该行)。我尝试了IsNewRow属性,但一旦您开始键入该行,就会添加另一个“新行”,因此您正在处理的行不再被视为新行。我知道该行尚未提交,因为您可以按Esc键取消编辑,而整行将消失 有没有一种方法可以判断当前编辑的行是否实际上是“新行”,因为它尚未提交回数据源?

我有一个客户端在Windows应用程序中的DataGridView出现问题。他们正在调用CellValidated事件,但如果单元格位于已提交回数据源的行中,他们希望对单元格进行不同的验证,而不是第一次添加(但尚未提交)的行(用户尚未离开该行)。我尝试了IsNewRow属性,但一旦您开始键入该行,就会添加另一个“新行”,因此您正在处理的行不再被视为新行。我知道该行尚未提交,因为您可以按Esc键取消编辑,而整行将消失


有没有一种方法可以判断当前编辑的行是否实际上是“新行”,因为它尚未提交回数据源?

我过去获得类似结果的一种方法是利用绑定到列表的对象的id属性

例如,如果我有一个
绑定列表
,其中的用户类似于:

public class Names
{
    public string Name { get; set; }         
    public int id { get; set; }
}
然后我可以像这样绑定我的列表:

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;
dataGridView1.AutoGenerateColumns=false;
_users=newbindingslist();
_添加(新名称(){Name=“joe”,id=1});
_添加(新名称(){Name=“pete”,id=2});
bindingSource1.DataSource=\u名称;
DataGridViewTextBoxColumn col1=新的DataGridViewTextBoxColumn();
col1.DataPropertyName=“Name”;
dataGridView1.Columns.Add(col1);
dataGridView1.DataSource=\u用户;
然后,当DataGridView提供新行时,它的id为0(整数的默认值)

来自数据库的每个对象都有一个非零id


使用BindingSources也可能有实现这一点的方法,但我快速查看了其中的属性,没有发现任何问题。

在这种情况下,数据源是什么

如果是datatable,则可以轻松测试datatable行的DataRowState属性,以查看它们是新的还是现有的。 验证数据行后,可以调用表上的Accept来提交这些行。 在这种情况下,不需要在网格和它的数据表之间进行干扰

当然,这并不意味着您的数据实际上被提交到了一个数据库(如果它最终存储在该数据库中的话),这将是另一个步骤

此外,我通常避免直接写入datagridview;相反,我将其设置为只读,并弹出一个添加/输入屏幕,该屏幕可以执行所需的任何验证


我不知道这些是否对您有用-如果我没有抓住要点,请告诉我。

GenericMeatUnit的答案对我不起作用,但它为我提供了足够的方法,让我找到一个可行的方法。我现在是如何检查的:

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

此if语句之所以有效,是因为在DataGridView中保留该行之前,它实际上还不存在于datatable中,因此datatable中的行数将等于新行的RowIndex,因为RowIndex是从零开始的。

这将帮助不使用datatable对象的人:

在CellBeginEdit事件中,将Tag属性设置为用于区分“新”行的某个值

private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
    if (e.RowIndex == dataGridView1.NewRowIndex)
        dataGridView1.Rows[e.RowIndex].Tag = true;
}
然后在验证事件中,您可以检查该值:

if (dataGridView1.Rows[e.RowIndex].Tag is bool 
    && (bool) dataGridView1.Rows[e.RowIndex].Tag)
{
    // new row code

    // after it's added, mark it as 'not new'
    dataGridView1.Rows[e.RowIndex].Tag = false;
}
else
{
    // existing row code
}

抱歉-这是我第一次使用堆栈溢出。我写了一个答案,不喜欢它,删除了它,写了一个更好的答案,不得不取消删除它。不管怎样,它在下面。希望它有帮助。这不起作用,因为当添加一行而您还没有离开该行时,该行在数据表中还不存在。正在尝试在行索引处访问该行r该行引发异常。然而,这确实帮助我找到了一种方法来实现这一点——检查该行是否存在于datasetI中,就像下面的答案一样,而且它似乎可以工作,但是由于我使用的是一个通用数据集,而不是一个对象集合,因此在这种情况下,我无法完全验证它。我投票支持它,因为它可以提供使用不幸的是,在不同的情况下都是ful。数据库中的行ID-s可以是任何数字,可以是负数、零或正数-这段代码取决于DBA()的善意