【问题标题】:C# DataGridView Adding a Row - When validating, how do I know the row is new and not yet committed?C# DataGridView 添加行 - 验证时,我如何知道该行是新行且尚未提交?
【发布时间】:2010-02-03 06:02:02
【问题描述】:

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

有没有办法判断当前编辑的行是否实际上是“新行”,因为它没有被提交回数据源?

【问题讨论】:

  • 抱歉 - 这是我第一次使用 Stack Overflow。我写了一个答案,不喜欢它,删除它,写了一个更好的答案,不得不取消删除它。无论如何,它在下面。希望对您有所帮助。

标签: c# winforms datagridview


【解决方案1】:

我过去实现类似的一种方法是利用绑定到列表的对象的 id 属性。

例如,如果我有一个BindingList<User>,其中用户类似于:

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;

然后,当 DataGridView 提供一个新行时,它的 id 将为 0(整数的默认值)。

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

也可能有一种方法可以使用 BindingSources 来实现这一点,但我快速浏览了那里的属性,并没有发现任何问题。

【讨论】:

  • 我喜欢这个答案,而且它似乎可以工作,但由于我使用的是通用数据集,而不是对象集合,因此在这种情况下我无法完全验证它。我投票赞成它,因为它可以在不同的情况下提供有用的信息,但不幸的是,在这种情况下没有。
  • 数据库中的行 ID-s 可以是任何数字,可以是负数、零或正数 - 此代码取决于 DBA (msdn.microsoft.com/en-us/library/ms176057.aspx) 的善意
【解决方案2】:

这种情况下的数据源是什么?

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

当然,这并不意味着您的数据实际上已提交到数据库,如果这是最终存储的位置。那将是另一个步骤。

另外,我通常避免直接写入数据网格视图;相反,我将其设为只读并弹出一个添加/输入屏幕,该屏幕可以执行任何所需的验证。

我不知道这是否对您有用 - 如果我错过了重点,请告诉我。

【讨论】:

  • 这不起作用,因为当正在添加一行并且您还没有离开该行时,它在数据表中还不存在。尝试访问该行的 RowIndex 处的行会引发异常。但是,这确实帮助我找到了一种方法来完成这项工作 - 检查该行是否存在于数据集中
【解决方案3】:

这应该可以帮助不使用 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
}

【讨论】:

    【解决方案4】:

    GenericMeatUnit 的回答对我不起作用,但它为我提供了足够的资源来找到使其工作的方法。以下是我现在的检查方式:

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

    此 if 语句有效,因为在将行留在 DataGridView 中之前,它实际上并不存在于数据表中,因此数据表中的行数将等于新行的 RowIndex,因为 RowIndex 为零- 基于。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-10
      • 1970-01-01
      相关资源
      最近更新 更多