【问题标题】:Compare 2 different columns in the datagridview比较 datagridview 中的 2 个不同的列
【发布时间】:2012-10-26 21:02:54
【问题描述】:

在我的datagridview 中,第 1 列和第 2 列四列是只读的,第 3 列和第 4 列有数字值。我想比较第 4 列必须大于第 3 列。 例如:

如果第 4 列的值小于第 3 列,那么我想建议消息不会导航到另一个控件。

我的简单方法似乎不起作用。如何针对这种情况比较 2 个特定列?

private void datagridview_CellValidating(object sender, CellValidatingEventArgs e)
{
    try
    {
        int bbor = datagridview.CurrentCell.ColumnIndex;
        int ebor = datagridview.CurrentCell.RowIndex;
        if (ebor <= bbor)
        {
            MessageBox.Show("Please verify the value");
            e.Cancel = true;
        }
    }
    catch (Exception exception)
    {
    }
}

【问题讨论】:

  • 为什么要比较列索引和行索引?从适当位置的每个单元格中获取值并比较值,而不是索引。
  • 在某些情况下,在 datagridview 中它可能有 8 行,我无法比较每一行。按行和列索引可能会更好。如果我错了,请纠正我。谢谢你;
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • 好的,对不起。我会记住的。
  • @linguini Lemme 知道您是否需要帮助我的答案,我们可以再次聊天。

标签: c# winforms datagridview telerik


【解决方案1】:

我们又见面了。使用 cell_click 事件:

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex != 0)
    {
        if (Double.Parse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()) <= Double.Parse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex - 1].Value.ToString()))
        {
            MessageBox.Show("Please verify the value");
        }
    }
}

编辑 1:这似乎工作正常,让我知道。

private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    if (e.ColumnIndex != 0)
    {
        if (Double.Parse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()) <= Double.Parse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex - 1].Value.ToString()))
        {
            MessageBox.Show("Please verify the value");
            e.Cancel = true;
        }
    }
}

编辑 2:针对 Telerik 控件进行了更新

private void radGridView1_CellValidating(object sender, Telerik.WinControls.UI.CellValidatingEventArgs e)
    {
        if (e.ColumnIndex != 0)
        {
            if (e.Value != null && radGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex - 1].Value != null)
            {
                if (Double.Parse(e.Value.ToString()) <= Double.Parse(radGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex - 1].Value.ToString()))
                {
                    MessageBox.Show("error");
                    e.Cancel = true;                        
                }
            }
        }
    }

【讨论】:

  • 很高兴再次见到你,谢谢。如果我使用 e.cancel,它似乎不起作用。
  • @linguini 您是否希望在他们更改值时弹出消息?或者您希望它在单击单元格时弹出?
  • 实际上,如果第 4 列值小于第 3 列值(从第一行开始),则用户不应导航到另一个单元格。这就是为什么我要尝试进行单元格验证。如果我错了纠正我。谢谢
  • @linguini 我在帖子中添加了一个编辑。我对其进行了测试,基本上它使用户关闭消息框,同时保持对当前需要处理的单元格的关注。你得到了什么,也许是一个错误?
【解决方案2】:

我或多或少会看到类似的东西:

如果要检查所有行:

DataRow dr;
for(int i = datagridview.Rows.Count-1; i > 0; i--) {
    dr = datagridview.Rows[i];
    if(dr[e.ColumnIndex] > dr[e.ColumnIndex+1]){
            //your message code     
            e.Cancel = true;
        break; (or return;)
    }
}

如果您只想检查正在编辑单元格的当前行:

DataRow dr = datagridview.Rows[e.RowIndex];
e.Cancel = dr[e.ColumnIndex] > dr[e.ColumnIndex+1];
if(e.Cancel)
    //your message code

也许您需要将对象转换为 int 以进行比较。

【讨论】:

    【解决方案3】:

    查看 DataGridView 的 Rows 属性http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.rows.aspx

    this.dataGridView1[col, row].Value

    为每一行引用一个特定的单元格

    foreach (Row r in this.dataGridView1.Rows) {
        if (r.Cells[3].Value <= r.Cells[2].Value ) {
        System.Console.WriteLine ("error");
        }
    }
    

    【讨论】:

    • 我没有完全理解你。我试过你的代码,它不起作用。
    • int cell = (int) r.Cells[2].Value; int 细胞 = (int) r.Cells[3].Value; if (cells
    【解决方案4】:

    对于您的验证检查,您需要使用FormattedValue property 来查看您的用户想要在他们编辑过的单元格中插入什么值。您不能使用当前单元格值,因为在 CellValidating 完成且 DataGridViewCellValidatingEventArgs.Cancel 未设置为 true 之前它不会更新为新值。

    类似这样的:

    private void datagridview_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
        // This is the new proposed value the user entered; could be for column 3 or 4.
        int newValue = int.Parse(e.FormattedValue.ToString());
    
        // See which column fired the CellValidating event and use the new proposed value for it
        // in place of the cell's actual value for purposes of our validation.
        int col3Value = (e.ColumnIndex == 2) ? newValue : (int)dataGridView1[2, e.RowIndex].Value;
        int col4Value = (e.ColumnIndex == 3) ? newValue : (int)dataGridView1[3, e.RowIndex].Value;
    
        if (col3Value <= col4Value) {
            MessageBox.Show("Please verify the value");
            e.Cancel = true;
        }
    }
    

    我在这里展示的代码是为了演示您的问题的解决方案。在您的实际生产代码中 您需要验证从 object 到 int 的转换是否成功(通过int.TryParse)或捕获此操作失败时引发的异常。发生这种情况时,您可以Cancel = true 单元格验证并向用户显示他必须输入数字的消息。

    还有一个简短的说明:don't use empty catch blocks(尽管我意识到这可能不在您的生产代码中)。

    【讨论】:

    • 我收到一条错误消息,无法将索引应用于表达式类型。
    • 您在哪一行得到错误?另外,您使用的是 DataGridView 吗?如果你是,那么你的第二个参数应该是 DataGridViewCellValidatingEventArgs 类型。
    猜你喜欢
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多