2

In my datagridview, four columns 1 & 2 are read only col 3 & 4 got number values. I want to compare that 4th column must be greater that 3rd column. For example:

enter image description here

If the 4th column value is less than the 3rd column then I want to propose message doesn't navigate to another control.

My simple approach seems not working. How can I compare 2 specific columns for this kind of condition?

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)
    {
    }
}
Ninjakannon
  • 3,751
  • 7
  • 53
  • 76
linguini
  • 1,939
  • 5
  • 49
  • 79
  • Why are you comparing the column and row indexes? Grab the value from each cell at the appropriate location and compare the values, not the indexes. – Michael Todd Nov 06 '12 at 20:41
  • In some cases, in the datagridview it may have 8 rows, I can't compare each and every row. BY row & col index may be better.. Please correct me if i'm wrong. Thank u; – linguini Nov 06 '12 at 20:45
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Nov 06 '12 at 20:59
  • Ok, i'm sorry. I'll keep it in mind. – linguini Nov 06 '12 at 21:01
  • @linguini Lemme know if you need help my answer and we can hit up chat again. – KreepN Nov 06 '12 at 21:52

4 Answers4

1

I'd see something more or less like that:

If you want to check all rows:

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;)
    }
}

If you want to check only the current row where the cell is being edited:

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

Maybe you will need to convert objects to int for comparison.

TTT
  • 1,848
  • 2
  • 30
  • 60
1

See the Rows Property for DataGridView http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.rows.aspx

this.dataGridView1[col, row].Value

references a specific cell for each row

foreach (Row r in this.dataGridView1.Rows) {
    if (r.Cells[3].Value <= r.Cells[2].Value ) {
    System.Console.WriteLine ("error");
    }
}
sammarcow
  • 2,736
  • 2
  • 28
  • 56
1

For your validation check you'll want to use the FormattedValue property to see what value your user wants to insert in the cell they've edited. You can't use the current cell value because it doesn't update to the new value until after the CellValidating completes without DataGridViewCellValidatingEventArgs.Cancel being set to true.

Something like this:

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;
    }
}

The code I show here is to demonstrate a solution to your problem. In your actual production code you'll want to verify that casting from object to int is successful (through int.TryParse) or catch the exception that's raised when this operation fails. When this happens you can Cancel = true the cell validation and present to the user a message that he must enter a number.

And another quick note: don't use empty catch blocks (though I realize this probably isn't in your production code).

Community
  • 1
  • 1
Jay Riggs
  • 53,046
  • 9
  • 139
  • 151
  • I'm getting a error message, can't apply indexing to an expression type. – linguini Nov 06 '12 at 21:48
  • On which line are you getting the error? Also, are you using a DataGridView? If you are then your second parameter should be of type `DataGridViewCellValidatingEventArgs`. – Jay Riggs Nov 06 '12 at 22:24
1

we meet again. Use the cell_click event:

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");
        }
    }
}

EDIT 1: This seems to work fine, lemme know.

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;
        }
    }
}

Edit 2: Updated for Telerik controls

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;                        
                }
            }
        }
    }

enter image description here

KreepN
  • 8,528
  • 1
  • 40
  • 58
  • Good to see you again, thank you. If i use e.cancel it's seems it's not working. – linguini Nov 06 '12 at 21:56
  • @linguini Are you wanting to have the message pop up when they change the value? Or are you wanting it to popup when clicking in the cell? – KreepN Nov 06 '12 at 22:07
  • Actually, If the 4th col value is less than 3rd Col value(right from the first row) then the user shouldn't navigate to another cell. Thats why i'm trying to cell validating. Correct me if i'm wrong. Thank you – linguini Nov 06 '12 at 22:10
  • @linguini I added an edit to my post. I tested it and basically it makes the user close the messagebox while maintaining focus on the current cell that needs to be addressed. What are you getting, an error perhaps? – KreepN Nov 06 '12 at 22:17
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/19181/discussion-between-linguini-and-kreepn) – linguini Nov 06 '12 at 22:18
  • I have sent an email to you. Thank you. – linguini Nov 07 '12 at 15:02
  • @linguini I'll check it out when I have a few minutes, working on a dev item atm :). I'll respond here when I do. – KreepN Nov 07 '12 at 15:06
  • @linguini I don't see an email, even in my junk. got_die@hotmail.com -> Try it again. – KreepN Nov 07 '12 at 15:18
  • àKreepN just sent once agin. – linguini Nov 07 '12 at 15:22