Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. dataGridView1_CellContentClick Error Index Out of Range

dataGridView1_CellContentClick Error Index Out of Range

Scheduled Pinned Locked Moved C#
cssdatabasehelpannouncement
16 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M MumbleB

    Luc, to start off, thanks for reference to your article. I have done that. :thumbsup: As for cleaning up my code, I am doing that. :thumbsup: As for your comment about being professional, a bit uncalled for but hey some peopl have bad days. To explain the problem: I have a form with a dataGridView on it. I also have a button on this form that loads the data grid with data from the Database. Only three columns: One is the ID column, which is an Autonumber, and the other two are Text columns. I am adding two extra columns to the dataGridView called Edit and Delete. Now, on the dataGridView1_CellContentClick event, when I click in any of the column/rows to edit data, I get an error. Full error message being, Index was out of range. Must be non-negatuve and less than the size of the collection. Parameter name: Index". Below is the code:

        private void dataGridView1\_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            int currentRow = e.RowIndex;
            int rowint = 0;
            dt.Clear();
            
            try
            {
                conn.Open();
                
                **string taskstring = dataGridView1\[0, currentRow\].Value.ToString();** //This is where the error is.
    

    In the above code, when a user clicks on a cell to edit the contents, the code has to do a check to see if the selected cell is an Edit or Delete Button Column. What seems to happen is that when I run this now, this morning in debug with a line break at the point where I get the error it seems to work. When running it in debug without the line break it does the following. Some times it selects the cell and other times it doesn't. However, it doesn't seem to be throwing the error. :((

    Excellence is doing ordinary things extraordinarily well.

    L Offline
    L Offline
    Luc Pattyn
    wrote on last edited by
    #7

    Kwagga wrote:

    string taskstring = dataGridView1[0, currentRow].Value.ToString(); /

    I see two indices in that statement. so what is the value of currentRow? and how many rows and columns are there at that point in time? (the number may vary when you have databindings). Is there a relationship between datagridview1 and dt (which you just cleared)? you still have work to do on the observation half of my previous message! :)

    Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

    Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

    1 Reply Last reply
    0
    • M MumbleB

      Ok, I have done two things. The error seems to come in here:

      string taskstring = dataGridView1[0, currentRow].Value.ToString();

      I have also re-writtent the currentRow as this which seems to work:

      int currentRow = e.RowIndex;

      So, with the error narrowed down, why do you think it does this on this form and not on the other?

      Excellence is doing ordinary things extraordinarily well.

      OriginalGriffO Offline
      OriginalGriffO Offline
      OriginalGriff
      wrote on last edited by
      #8

      Kwagga wrote:

      I have also re-writtent the currentRow as this which seems to work: int currentRow = e.RowIndex;

      Yes, that is what I would expect - and int assigned directly to an int! See how much easier it is when you don't convert int to string to int? :laugh:

      Kwagga wrote:

      The error seems to come in here: string taskstring = dataGridView1[0, currentRow].Value.ToString();

      That only leaves one option: currentRow has a value that is either negative, or too big for the DataGridView. Since you access it from the RowIndex, it is unlikely to be too big - how would it unless the DatatGridView is being modified by some outside agency; not too likley in your scenario I think. That leaves negative. And I'm betting that is what the problem is. The easiest way to get a negative number here via the RowIndex (in fact the only one I know, but I've been wrong before) is to click on the column header. Are you by any chance doing that? If not, then insert a check for negative (and out-of-range) values and see what you get. I'm pretty confident that either your code for the other DataGridViews is different and checks for valid data or you haven't clicked on their column header yet... :-D

      Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.

      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
      "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

      M 1 Reply Last reply
      0
      • L Luc Pattyn

        you should clean up your code first. 1. there is an abundance of unnecessary calls to ToString() e.g. Exception.Message is a string, calling ToString on it does nothing useful at all. 2. it does not make sense to convert a number to a string and then back to a number. stop doing that right now. 3. there is a test for currentRow>=0 somewhere in your code. Why is that? either it is not necessary and you must remove it; or it is necessary, which also means dataGridView1[0, currentRow] can get a bad index. Check the documentation, log the values, do whatever it takes, but make this consistent. Then you must use all available information: 1. when an exception occurs, show all of it, not just the message itself. This is the one place you absolutely should use ToString(). Yes it will generate maybe 20 or 30 lines of information, some of that is really useful. 2. make sure your development tools (Visual Studio or other) ALWAYS show line numbers in editor windows. See #101 and #102 here[^]. As a result an excpetion will be pinpointed to the right line without any doubt. 3. when an exception occurs, also show additional information. In this case show e.RowIndex, e.ColumnIndex, and whatever you think may be relevant. So next time it throws, you get all of it at a glance. So start behaving more professionally, clean up, observe, and fix the remaining problems. :)

        Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

        Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

        OriginalGriffO Offline
        OriginalGriffO Offline
        OriginalGriff
        wrote on last edited by
        #9

        Hi Luc! How are you doing today?

        Luc Pattyn wrote:

        make sure your development tools (Visual Studio or other) ALWAYS show line numbers in editor windows.

        You don't need to do this: VS shows the row and column numbers on the status line by default, and CTRL+G will take to to an absolute page number. I use this rather than waste screen real-estate and adding unnecessary confusion to the display! Different stroke for different folks, I guess. :laugh:

        Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.

        "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
        "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

        L 1 Reply Last reply
        0
        • OriginalGriffO OriginalGriff

          Hi Luc! How are you doing today?

          Luc Pattyn wrote:

          make sure your development tools (Visual Studio or other) ALWAYS show line numbers in editor windows.

          You don't need to do this: VS shows the row and column numbers on the status line by default, and CTRL+G will take to to an absolute page number. I use this rather than waste screen real-estate and adding unnecessary confusion to the display! Different stroke for different folks, I guess. :laugh:

          Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #10

          OriginalGriff wrote:

          How are you doing today?

          Fine, thanks. Although I can't find the hidden message I'm sure you must have hidden in there. I won't be around much the next couple of days, a major chess tournament is about to start.

          OriginalGriff wrote:

          You don't need to do this

          I know. Nevertheless those few characters on each line are the most useful data in there anyway, the remainder being just too many int.Parse(something.ToString()) and the like. I much prefer all those enquirers to at least discover for themselves which line is causing havoc. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

          Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

          OriginalGriffO M 2 Replies Last reply
          0
          • L Luc Pattyn

            OriginalGriff wrote:

            How are you doing today?

            Fine, thanks. Although I can't find the hidden message I'm sure you must have hidden in there. I won't be around much the next couple of days, a major chess tournament is about to start.

            OriginalGriff wrote:

            You don't need to do this

            I know. Nevertheless those few characters on each line are the most useful data in there anyway, the remainder being just too many int.Parse(something.ToString()) and the like. I much prefer all those enquirers to at least discover for themselves which line is causing havoc. :)

            Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

            Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

            OriginalGriffO Offline
            OriginalGriffO Offline
            OriginalGriff
            wrote on last edited by
            #11

            Luc Pattyn wrote:

            a major chess tournament is about to start.

            Good luck!

            Luc Pattyn wrote:

            I can't find the hidden message I'm sure you must have hidden in there

            No, no - I wouldn't do that!

            Luc Pattyn wrote:

            those few characters on each line are the most useful data in there

            I'm not too sure about that - I would agree that they are the most accurate data in many peoples software, though!

            Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.

            The badgers fly south in august. Peppermint discus tower emblem.

            "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
            "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

            1 Reply Last reply
            0
            • OriginalGriffO OriginalGriff

              Kwagga wrote:

              I have also re-writtent the currentRow as this which seems to work: int currentRow = e.RowIndex;

              Yes, that is what I would expect - and int assigned directly to an int! See how much easier it is when you don't convert int to string to int? :laugh:

              Kwagga wrote:

              The error seems to come in here: string taskstring = dataGridView1[0, currentRow].Value.ToString();

              That only leaves one option: currentRow has a value that is either negative, or too big for the DataGridView. Since you access it from the RowIndex, it is unlikely to be too big - how would it unless the DatatGridView is being modified by some outside agency; not too likley in your scenario I think. That leaves negative. And I'm betting that is what the problem is. The easiest way to get a negative number here via the RowIndex (in fact the only one I know, but I've been wrong before) is to click on the column header. Are you by any chance doing that? If not, then insert a check for negative (and out-of-range) values and see what you get. I'm pretty confident that either your code for the other DataGridViews is different and checks for valid data or you haven't clicked on their column header yet... :-D

              Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.

              M Offline
              M Offline
              MumbleB
              wrote on last edited by
              #12

              Yeah, it is much easier. LOL..... I haven't clicked on any of the header rows. What I have noticed though is that when I click in the cell I want to Edit it just goes back to the first cell. When I click it again then it throws the error. Honestly, the code for the other gridviews are exactly the same for the cellcontent_click event. I am about to give up and just leave them out of the project and then every time somebody has to have something changed for them to go direct to the DB. I have pulled out most of my hair by now!!!!

              Excellence is doing ordinary things extraordinarily well.

              1 Reply Last reply
              0
              • L Luc Pattyn

                OriginalGriff wrote:

                How are you doing today?

                Fine, thanks. Although I can't find the hidden message I'm sure you must have hidden in there. I won't be around much the next couple of days, a major chess tournament is about to start.

                OriginalGriff wrote:

                You don't need to do this

                I know. Nevertheless those few characters on each line are the most useful data in there anyway, the remainder being just too many int.Parse(something.ToString()) and the like. I much prefer all those enquirers to at least discover for themselves which line is causing havoc. :)

                Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

                Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

                M Offline
                M Offline
                MumbleB
                wrote on last edited by
                #13

                Guys, I thank you for the help thus far. I think I have resolved the problem. The problem seems to have been in the connection state. I added a bunch of checks to see fi the connection was open or closed and then opening, or closing it depending on the state and that seems to have resolved the issue. Below is a work in progress, I am still trying to clean this up a bit more by passing parameters to my SQL statements. Thanks again for the help guys.

                    private void dataGridView1\_CellContentClick(object sender, DataGridViewCellEventArgs e)
                    {
                        int currentRow = e.RowIndex;
                        int rowint = 0;
                        try
                        {
                            string taskstring = dataGridView1\[0, currentRow\].Value.ToString();
                            rowint = int.Parse(taskstring);
                            if (dataGridView1.Columns\[e.ColumnIndex\] == deleteButton && currentRow >= 0)
                            {
                                if (conn.State == ConnectionState.Open)
                                {
                                    conn.Close();
                                }
                                else
                                {
                                    conn.Open();
                                    OleDbCommand sqlDelete = new OleDbCommand("DELETE FROM tblTasks where TaskCode = @rowint", conn);
                                    OleDbParameter param = new OleDbParameter();
                                    param.ParameterName = "@rowint";
                                    param.Value = rowint;
                                    sqlDelete.Parameters.Add(param);
                                    sqlDelete.ExecuteNonQuery();
                                    getData();
                                }
                            }
                            if (dataGridView1.Columns\[e.ColumnIndex\] == editButton && currentRow >= 0)
                            {
                                if (conn.State == ConnectionState.Open)
                                {
                                    conn.Close();
                                }
                                else
                                {
                                    conn.Open();
                                    string updatestring = "Select TaskCode, TaskName, TaskDescription FROM tblTasks WHERE TaskCode = " + rowint + "";
                                    string taskname = dataGridView1\[dataGridView1.Columns\["TaskName"\].Index, currentRow\].Value.ToString();
                                    string description = dataGridView1\[dataGridView1.Columns\["TaskDescription"\].Index, currentRow\].Value.ToString();
                                    OleDbDataAdapter da = new OleDbDataAdapter(updatestring, conn);
                                    OleDbCommandBuilder cmdb = new
                
                OriginalGriffO 1 Reply Last reply
                0
                • M MumbleB

                  Guys, I thank you for the help thus far. I think I have resolved the problem. The problem seems to have been in the connection state. I added a bunch of checks to see fi the connection was open or closed and then opening, or closing it depending on the state and that seems to have resolved the issue. Below is a work in progress, I am still trying to clean this up a bit more by passing parameters to my SQL statements. Thanks again for the help guys.

                      private void dataGridView1\_CellContentClick(object sender, DataGridViewCellEventArgs e)
                      {
                          int currentRow = e.RowIndex;
                          int rowint = 0;
                          try
                          {
                              string taskstring = dataGridView1\[0, currentRow\].Value.ToString();
                              rowint = int.Parse(taskstring);
                              if (dataGridView1.Columns\[e.ColumnIndex\] == deleteButton && currentRow >= 0)
                              {
                                  if (conn.State == ConnectionState.Open)
                                  {
                                      conn.Close();
                                  }
                                  else
                                  {
                                      conn.Open();
                                      OleDbCommand sqlDelete = new OleDbCommand("DELETE FROM tblTasks where TaskCode = @rowint", conn);
                                      OleDbParameter param = new OleDbParameter();
                                      param.ParameterName = "@rowint";
                                      param.Value = rowint;
                                      sqlDelete.Parameters.Add(param);
                                      sqlDelete.ExecuteNonQuery();
                                      getData();
                                  }
                              }
                              if (dataGridView1.Columns\[e.ColumnIndex\] == editButton && currentRow >= 0)
                              {
                                  if (conn.State == ConnectionState.Open)
                                  {
                                      conn.Close();
                                  }
                                  else
                                  {
                                      conn.Open();
                                      string updatestring = "Select TaskCode, TaskName, TaskDescription FROM tblTasks WHERE TaskCode = " + rowint + "";
                                      string taskname = dataGridView1\[dataGridView1.Columns\["TaskName"\].Index, currentRow\].Value.ToString();
                                      string description = dataGridView1\[dataGridView1.Columns\["TaskDescription"\].Index, currentRow\].Value.ToString();
                                      OleDbDataAdapter da = new OleDbDataAdapter(updatestring, conn);
                                      OleDbCommandBuilder cmdb = new
                  
                  OriginalGriffO Offline
                  OriginalGriffO Offline
                  OriginalGriff
                  wrote on last edited by
                  #14

                  Using parameters is a very good idea - but there is a nicer way:

                                      OleDbCommand sqlDelete = new OleDbCommand("DELETE FROM tblTasks where TaskCode = @rowint", conn);
                                      OleDbParameter param = new OleDbParameter();
                                      param.ParameterName = "@rowint";
                                      param.Value = rowint;
                                      sqlDelete.Parameters.Add(param);
                  

                  Becomes:

                                      OleDbCommand sqlDelete = new OleDbCommand("DELETE FROM tblTasks where TaskCode = @rowint", conn);
                                      sqlDelete.Parameters.AddWithValue("@rowint", rowint);
                  

                  Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.

                  "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                  "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                  M 1 Reply Last reply
                  0
                  • OriginalGriffO OriginalGriff

                    Using parameters is a very good idea - but there is a nicer way:

                                        OleDbCommand sqlDelete = new OleDbCommand("DELETE FROM tblTasks where TaskCode = @rowint", conn);
                                        OleDbParameter param = new OleDbParameter();
                                        param.ParameterName = "@rowint";
                                        param.Value = rowint;
                                        sqlDelete.Parameters.Add(param);
                    

                    Becomes:

                                        OleDbCommand sqlDelete = new OleDbCommand("DELETE FROM tblTasks where TaskCode = @rowint", conn);
                                        sqlDelete.Parameters.AddWithValue("@rowint", rowint);
                    

                    Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.

                    M Offline
                    M Offline
                    MumbleB
                    wrote on last edited by
                    #15

                    Thanks Griff. How would I write one for multiple columns UPDATE? Been searching and most posts only shows 1 parameter being passed at a time

                    Excellence is doing ordinary things extraordinarily well.

                    OriginalGriffO 1 Reply Last reply
                    0
                    • M MumbleB

                      Thanks Griff. How would I write one for multiple columns UPDATE? Been searching and most posts only shows 1 parameter being passed at a time

                      Excellence is doing ordinary things extraordinarily well.

                      OriginalGriffO Offline
                      OriginalGriffO Offline
                      OriginalGriff
                      wrote on last edited by
                      #16

                      CLUE:

                      UPDATE mytable SET field1=@F1,field2=@F2 WHERE field3=@F3

                      cmd.AddWithValue("@F1", "111");
                      cmd.AddWithValue("@F2", "222");
                      ...

                      Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.

                      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                      "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups