DataGridView验证旧值而不是新值

5

我有一个DataGridView控件,它绑定了一个DataTable对象,其中有一列是双精度浮点型,其值必须在0和1之间。以下是我的代码:

private void dgvImpRDP_InfinityRDPLogin_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    if (e.ColumnIndex == dtxtPercentageOfUsersAllowed.Index)
    {
        double percentage;
        if(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value.GetType() == typeof(double))
            percentage = (double)dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value;
        else if (!double.TryParse(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value.ToString(), out percentage))
        {
            e.Cancel = true;
            dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
            return;
        }
        if (percentage < 0 || percentage > 1)
        {
            e.Cancel = true;
            dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
        }
    }
}

然而,我的问题是当dgvImpRDP_InfinityRDPLogin_CellValidating触发时,dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value将包含编辑之前的旧值,而不是新值。

例如,假设旧值为.1,我输入3。当你退出单元格并运行上述代码时,dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value将为该运行提供.1,代码验证并将数据写入DataTable中的3

我第二次点击它,试图离开,这次它的行为就像它应该的那样,它为单元格引发错误图标并防止我离开。我试图输入正确的值(比如.7),但Value仍然是3,因为由于错误而锁定了单元格,并且我的验证代码永远不会推送新值。

任何建议都将不胜感激。

编辑-- 根据Stuart的建议和模仿MSDN文章的风格,编写了新版本的代码。仍然表现相同。

private void dgvImpRDP_InfinityRDPLogin_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    if (e.ColumnIndex == dtxtPercentageOfUsersAllowed.Index)
    {
        dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = String.Empty;
        double percentage;
        if (!double.TryParse(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].FormattedValue.ToString(), out percentage) || percentage < 0 || percentage > 1)
        {
            e.Cancel = true;
            dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
            return;
        }
    }
}
2个回答

4
您需要使用DataGridViewCellValidatingEventArgs实例的FormattedValue属性而不是单元格值,因为单元格值在验证成功之前不会更新:
用户通过用户界面(UI)输入的文本成为FormattedValue属性值。这是您可以在将其解析为单元格Value属性值之前进行验证的值。(MSDN)

不对,我输入了5之后,dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].FormattedValue 的值是".1"。 - Scott Chamberlain
1
不对,你需要查看 e.FormattedValue! - stuartd

1

你可以尝试这样做,假设你在datagridview中使用的是文本框,如果你使用其他控件,只需将其更改为相应的控件即可。(虽然我不确定为什么Stuart Dunkeld的答案不起作用,FormattedValue应该包含新值)。

  void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
  {
     if (e.ColumnIndex == 0) // dtxtPercentageOfUsersAllowed.Index
     {
        object should_be_new_value = e.FormattedValue;
        double percentage;
        if (dgvImpRDP_InfinityRDPLogin.EditingControl != null)
        {
           string text = dgvImpRDP_InfinityRDPLogin.EditingControl.Text;
           if (!double.TryParse(text, out percentage))
           {
              e.Cancel = true;
              dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
              return;
           }
           if (percentage < 0 || percentage > 1)
           {
              e.Cancel = true;
              dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1";
           }
           else
           {
              dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = null;
           }
        }
     }
  }

没问题。我只是稍微修改了一下,使用文本而不是检查类型。应该会得到相同的结果,只是更加简洁。但如果有问题,请告诉我,我会将帖子恢复原样。 - SwDevMan81
它失败是因为如果您正在验证且当前没有编辑任何框,则EditingControll可能为空。 - Scott Chamberlain
好的,我添加了对空EditingControl的检查。 - SwDevMan81

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接