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. Web Development
  3. ASP.NET
  4. Deleting a row from a datagrid with checkboxes???

Deleting a row from a datagrid with checkboxes???

Scheduled Pinned Locked Moved ASP.NET
databasehtmlwpfwcfdesign
9 Posts 2 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.
  • I Offline
    I Offline
    Ironsmith1977
    wrote on last edited by
    #1

    Ok, I've been working on this for two days, even my instructor is lost on this one (not at all very encouraging). I'm making a shopping cart and based on which check box is selected, I need to delete that row out of the DataGrid. I'm not using SQL or any other database, though I do know its more efficient. I'm binding a DataTable to my DataGrid, and I know that I have to remove the row from the DataTable and then rebind it to the DataGrid. All of the columns and rows for the DataGrid are created in code, with the exception of the Check box column, that one I adding in HTML view. Here is a sample of how I'm creating my DataTable and then Binding it to the DataGrid, along with the Click event that should remove the row. private void imgbutSubmit_Click(object sender, System.Web.UI.ImageClickEventArgs e) { //CREATE A DATATABLE AND PUT IT INTO SESSION STATE. DataTable dt = null; if (Session["Items"] != null) { dt = (DataTable)Session["Items"]; } else { //CREATE THE COLUMNS FOR THE DATATABLE dt = new DataTable(); dt.Columns.Add("Brand"); dt.Columns.Add("Color"); dt.Columns.Add("Material"); dt.Columns.Add("Size"); dt.Columns.Add("Quantity"); dt.Columns.Add("Price"); } //CREATE THE ROWS FOR THE DATATABLE. DataRow dr = dt.NewRow(); dr["Brand"] = drpBrand.SelectedItem.Value; dr["Color"] = drpColor.SelectedItem.Value; dr["Material"] = drpMaterial.SelectedItem.Value; dr["Size"] = null; dr["Quantity"] = txtQuantity.Text; dr["Price"] = lblPrice.Text; dt.Rows.Add(dr); //ADD THE DATATABLE TO SESSION STATE. Session["Items"] = dt; } private void Page_Load(object sender, System.EventArgs e) { //CHECK IF THERE ARE ANY ITEMS IN THE CART. if (Session["Items"] == null) { lblEmpty.Text = "There are currently no items in your shopping cart."; } //BIND THE DATATABLE TO THE DATAGRID. if (!IsPostBack) { if (Session["Items"] != null) { DataTable dt = (DataTable)Session["Items"]; PurchaseDataGrid.DataSource = dt; PurchaseDataGrid.DataBind(); PurchaseDataGrid.DataKeyField = "Remove"; } } } private void btnRemove_Click(object sender, System.EventArgs e) { DataTable dt = (DataTable)Session["Items"]; PurchaseDataGrid.DataKeyField = "Remove"; int index = 0; foreach(DataGridItem item in PurchaseDataGrid.Items) { CheckBox chkRemove = item.Cells[0].Controls[1] as CheckBox; if (chkRemove.Checked

    M 1 Reply Last reply
    0
    • I Ironsmith1977

      Ok, I've been working on this for two days, even my instructor is lost on this one (not at all very encouraging). I'm making a shopping cart and based on which check box is selected, I need to delete that row out of the DataGrid. I'm not using SQL or any other database, though I do know its more efficient. I'm binding a DataTable to my DataGrid, and I know that I have to remove the row from the DataTable and then rebind it to the DataGrid. All of the columns and rows for the DataGrid are created in code, with the exception of the Check box column, that one I adding in HTML view. Here is a sample of how I'm creating my DataTable and then Binding it to the DataGrid, along with the Click event that should remove the row. private void imgbutSubmit_Click(object sender, System.Web.UI.ImageClickEventArgs e) { //CREATE A DATATABLE AND PUT IT INTO SESSION STATE. DataTable dt = null; if (Session["Items"] != null) { dt = (DataTable)Session["Items"]; } else { //CREATE THE COLUMNS FOR THE DATATABLE dt = new DataTable(); dt.Columns.Add("Brand"); dt.Columns.Add("Color"); dt.Columns.Add("Material"); dt.Columns.Add("Size"); dt.Columns.Add("Quantity"); dt.Columns.Add("Price"); } //CREATE THE ROWS FOR THE DATATABLE. DataRow dr = dt.NewRow(); dr["Brand"] = drpBrand.SelectedItem.Value; dr["Color"] = drpColor.SelectedItem.Value; dr["Material"] = drpMaterial.SelectedItem.Value; dr["Size"] = null; dr["Quantity"] = txtQuantity.Text; dr["Price"] = lblPrice.Text; dt.Rows.Add(dr); //ADD THE DATATABLE TO SESSION STATE. Session["Items"] = dt; } private void Page_Load(object sender, System.EventArgs e) { //CHECK IF THERE ARE ANY ITEMS IN THE CART. if (Session["Items"] == null) { lblEmpty.Text = "There are currently no items in your shopping cart."; } //BIND THE DATATABLE TO THE DATAGRID. if (!IsPostBack) { if (Session["Items"] != null) { DataTable dt = (DataTable)Session["Items"]; PurchaseDataGrid.DataSource = dt; PurchaseDataGrid.DataBind(); PurchaseDataGrid.DataKeyField = "Remove"; } } } private void btnRemove_Click(object sender, System.EventArgs e) { DataTable dt = (DataTable)Session["Items"]; PurchaseDataGrid.DataKeyField = "Remove"; int index = 0; foreach(DataGridItem item in PurchaseDataGrid.Items) { CheckBox chkRemove = item.Cells[0].Controls[1] as CheckBox; if (chkRemove.Checked

      M Offline
      M Offline
      Mike Ellison
      wrote on last edited by
      #2

      Hi there. Whenever you inspect DataGrid items, realize that the DataGridItem.ItemType may be any of a number of types, including Item, AlternatingItem, Header, Footer, and more. My guess is that the error is occuring on this line in btnRemove_Click():

      CheckBox chkRemove = item.Cells[0].Controls[1] as CheckBox;

      It may be that you are looking at a DataGridItem of the ItemType Header; its Cells[0] probably has only one literal control in it (the header text), so testing Controls[1] is probably giving an error. You would want to check the ItemType as the first line in your foreach block... something like this perhaps:

      foreach DataGridItem item in PurchaseDataGrid.Items)
      {
      if (item.ItemType == ListItemType.Item
      || item.ItemType == ListItemType.AlternatingItem)
      {
      // ... then continue with your Checkbox inspecting code
      }
      }

      I 1 Reply Last reply
      0
      • M Mike Ellison

        Hi there. Whenever you inspect DataGrid items, realize that the DataGridItem.ItemType may be any of a number of types, including Item, AlternatingItem, Header, Footer, and more. My guess is that the error is occuring on this line in btnRemove_Click():

        CheckBox chkRemove = item.Cells[0].Controls[1] as CheckBox;

        It may be that you are looking at a DataGridItem of the ItemType Header; its Cells[0] probably has only one literal control in it (the header text), so testing Controls[1] is probably giving an error. You would want to check the ItemType as the first line in your foreach block... something like this perhaps:

        foreach DataGridItem item in PurchaseDataGrid.Items)
        {
        if (item.ItemType == ListItemType.Item
        || item.ItemType == ListItemType.AlternatingItem)
        {
        // ... then continue with your Checkbox inspecting code
        }
        }

        I Offline
        I Offline
        Ironsmith1977
        wrote on last edited by
        #3

        Hello, I'm still getting the same error "Index out of range". Is it possibly because I specify the "int index = 0;" variable instead of a column heading? But I tried to specify a column heading and of course got a "cannot convert to string" error. See I can write: private void btnRemove_Click(object sender, System.EventArgs e) { DataTable dt = (DataTable)Session["Items"]; // PurchaseDataGrid.DataKeyField = "Remove"; int index = 0; foreach(DataGridItem item in PurchaseDataGrid.Items) { CheckBox chkRemove = item.Cells[0].Controls[1] as CheckBox; if (chkRemove.Checked == true) { // string id = PurchaseDataGrid.DataKeys[index] as string; // DataRow[] rows = dt.Select("Item='"+ id + "'"); // rows[0].Delete(); dt.Rows[0].Delete(); } } Session["Items"] = dt; PurchaseDataGrid.DataSource = dt; PurchaseDataGrid.DataBind(); } And this code removes the first row in the table. But this code at least checks to make sure that a checkbox is selected. Ironsmith

        M 1 Reply Last reply
        0
        • I Ironsmith1977

          Hello, I'm still getting the same error "Index out of range". Is it possibly because I specify the "int index = 0;" variable instead of a column heading? But I tried to specify a column heading and of course got a "cannot convert to string" error. See I can write: private void btnRemove_Click(object sender, System.EventArgs e) { DataTable dt = (DataTable)Session["Items"]; // PurchaseDataGrid.DataKeyField = "Remove"; int index = 0; foreach(DataGridItem item in PurchaseDataGrid.Items) { CheckBox chkRemove = item.Cells[0].Controls[1] as CheckBox; if (chkRemove.Checked == true) { // string id = PurchaseDataGrid.DataKeys[index] as string; // DataRow[] rows = dt.Select("Item='"+ id + "'"); // rows[0].Delete(); dt.Rows[0].Delete(); } } Session["Items"] = dt; PurchaseDataGrid.DataSource = dt; PurchaseDataGrid.DataBind(); } And this code removes the first row in the table. But this code at least checks to make sure that a checkbox is selected. Ironsmith

          M Offline
          M Offline
          Mike Ellison
          wrote on last edited by
          #4

          Hi there. I want to make sure you understood what I meant in my original reply. In your line

          CheckBox chkRemove = item.Cells[0].Controls[1] as CheckBox;

          you are assuming that item.Cells[0] has at least two Controls in it. Controls[0] would reference the first, and Controls[1] would reference the second. So in your code, you are saying "assign to the variable chkRemove a reference to the second control in the item's first cell. But what if the item's first cell doesn't contain two controls? What if it only contains one? In that case, a reference to item.Cells[0].Controls[1] would give an "index out of range" exception because the index "1" is out of range. In your typical Item, you probably do have two controls in that checkbox cell. But in, say, a Header item you probably only have one control in that cell (probably a header label). This is why I suggested before that you test the ItemType of the item, to make sure you are working with Item or AlternatingItem types only, and ignoring others (like Header types). I hope this makes sense.

          I 1 Reply Last reply
          0
          • M Mike Ellison

            Hi there. I want to make sure you understood what I meant in my original reply. In your line

            CheckBox chkRemove = item.Cells[0].Controls[1] as CheckBox;

            you are assuming that item.Cells[0] has at least two Controls in it. Controls[0] would reference the first, and Controls[1] would reference the second. So in your code, you are saying "assign to the variable chkRemove a reference to the second control in the item's first cell. But what if the item's first cell doesn't contain two controls? What if it only contains one? In that case, a reference to item.Cells[0].Controls[1] would give an "index out of range" exception because the index "1" is out of range. In your typical Item, you probably do have two controls in that checkbox cell. But in, say, a Header item you probably only have one control in that cell (probably a header label). This is why I suggested before that you test the ItemType of the item, to make sure you are working with Item or AlternatingItem types only, and ignoring others (like Header types). I hope this makes sense.

            I Offline
            I Offline
            Ironsmith1977
            wrote on last edited by
            #5

            Ok, I didn't get it the first time, but thank you for clearing that up for me. Your right, that would be referencing the header, which only says "Remove", however, I didn't put a label on it or use any templates, I just added it in HTML view. So I tried to adjust the cell and controls indexes but that didn't work out so well. so I changed Controls[1] to Controls[0]. And now I get this error "Object reference not set to an instance of an object." And its highlighting the: if (chkRemove.Checked) { It's not getting any further than this. Take care Ironsmith

            M 1 Reply Last reply
            0
            • I Ironsmith1977

              Ok, I didn't get it the first time, but thank you for clearing that up for me. Your right, that would be referencing the header, which only says "Remove", however, I didn't put a label on it or use any templates, I just added it in HTML view. So I tried to adjust the cell and controls indexes but that didn't work out so well. so I changed Controls[1] to Controls[0]. And now I get this error "Object reference not set to an instance of an object." And its highlighting the: if (chkRemove.Checked) { It's not getting any further than this. Take care Ironsmith

              M Offline
              M Offline
              Mike Ellison
              wrote on last edited by
              #6

              Okay - we'll get there. Each DataGridItem has an ItemType property that tells you what kind of row it is. If the ItemType is ListItemType.Item or ListItemType.AlternatingItem, it means it is a normal detail row. If the ItemType is ListItemType.Header, it means the item is a header row. What you want to do in your code is ignore any DataGridItem that represents a header row - or better put, only concern yourself with normal detail rows, identified by ListItemType.Item or ListItemType.AlternatingItem. Once you know you are working with a normal detail row, then you can grab a reference to the checkbox. Is the checkbox in the item's first cell? If so you want to reference Cells[0]. If it's in the second cell, reference Cells[1], third cell is referenced by Cells[2], and so on. Once you have the proper cell, then determine if the checkbox is the first, or second, or third, etc. control within that cell. If it is the first, then reference it with Controls[0]; if it is the second, reference it with Controls[1]; for the third, Controls[2], etc. Here's another shot at what I was getting at in my first response. This is your foreach loop, looping through each DataGridItem in the grid:

              foreach (DataGridItem item in PurchaseDataGrid.Items)
              {
              // first, ignore any type other than Item or AlternatingItem;
              // this ensures that we won't be messing around with Headers,
              // Footers, or other row types that aren't appropriate for us

              if (item.ItemType == ListItemType.Item
              || item.ItemType == ListItemType.AlternatingItem)
              {
              // now we know this item represents a normal detail row, in which
              // we have a cell with a checkbox. Let's get a reference to that
              // checkbox control. Assuming it's in the first cell, we'll reference
              // the cell as Cells[0]. Assuming within that cell, the checkbox is
              // the second control, we'll reference it with Controls[1]:

               CheckBox chkRemove = item.Cells\[0\].Controls\[1\] as CheckBox;
               
               // now we can test to see if the checkbox is checked or not
               if (chkRemove.Checked)
               { 
                 //... and execute any code accordingly
               }
              

              }
              }

              I hope this helps.

              I 1 Reply Last reply
              0
              • M Mike Ellison

                Okay - we'll get there. Each DataGridItem has an ItemType property that tells you what kind of row it is. If the ItemType is ListItemType.Item or ListItemType.AlternatingItem, it means it is a normal detail row. If the ItemType is ListItemType.Header, it means the item is a header row. What you want to do in your code is ignore any DataGridItem that represents a header row - or better put, only concern yourself with normal detail rows, identified by ListItemType.Item or ListItemType.AlternatingItem. Once you know you are working with a normal detail row, then you can grab a reference to the checkbox. Is the checkbox in the item's first cell? If so you want to reference Cells[0]. If it's in the second cell, reference Cells[1], third cell is referenced by Cells[2], and so on. Once you have the proper cell, then determine if the checkbox is the first, or second, or third, etc. control within that cell. If it is the first, then reference it with Controls[0]; if it is the second, reference it with Controls[1]; for the third, Controls[2], etc. Here's another shot at what I was getting at in my first response. This is your foreach loop, looping through each DataGridItem in the grid:

                foreach (DataGridItem item in PurchaseDataGrid.Items)
                {
                // first, ignore any type other than Item or AlternatingItem;
                // this ensures that we won't be messing around with Headers,
                // Footers, or other row types that aren't appropriate for us

                if (item.ItemType == ListItemType.Item
                || item.ItemType == ListItemType.AlternatingItem)
                {
                // now we know this item represents a normal detail row, in which
                // we have a cell with a checkbox. Let's get a reference to that
                // checkbox control. Assuming it's in the first cell, we'll reference
                // the cell as Cells[0]. Assuming within that cell, the checkbox is
                // the second control, we'll reference it with Controls[1]:

                 CheckBox chkRemove = item.Cells\[0\].Controls\[1\] as CheckBox;
                 
                 // now we can test to see if the checkbox is checked or not
                 if (chkRemove.Checked)
                 { 
                   //... and execute any code accordingly
                 }
                

                }
                }

                I hope this helps.

                I Offline
                I Offline
                Ironsmith1977
                wrote on last edited by
                #7

                Ok, well it's an improvement, now its making it this far: string id = PurchaseDataGrid.DataKeys[index] as string; However, now I'm getting this error: "Must be non-negative and less than the size of the collection. Parameter name: index" I have no idea what this means, I'm thinking that because I don't have an "itemID" column, its conflicting with the strings in the table. But that's really just a guess. Also, should I be specifying a column name anywhere? Take care Ironsmith

                M 1 Reply Last reply
                0
                • I Ironsmith1977

                  Ok, well it's an improvement, now its making it this far: string id = PurchaseDataGrid.DataKeys[index] as string; However, now I'm getting this error: "Must be non-negative and less than the size of the collection. Parameter name: index" I have no idea what this means, I'm thinking that because I don't have an "itemID" column, its conflicting with the strings in the table. But that's really just a guess. Also, should I be specifying a column name anywhere? Take care Ironsmith

                  M Offline
                  M Offline
                  Mike Ellison
                  wrote on last edited by
                  #8

                  It looks like this is the code you're using to delete rows from the DataTable:

                  DataRow[] rows = dt.Select("Item='"+ id + "'");
                  rows[0].Delete();

                  I'm guessing that the reference rows[0] isn't valid here. Perhaps dt.Select("Item='" + id + "'") isn't returning any rows? Check that. I would re-read the documentation on DataKeys and DataKeyField as well. Make sure you understand what they are there for. You want the DataKeyField to be a field with values that uniquely identify each row. Then you can use DataKeys[index] where index is the ItemIndex of the DataGridItem to give you a unique id for the datarow.

                  I 1 Reply Last reply
                  0
                  • M Mike Ellison

                    It looks like this is the code you're using to delete rows from the DataTable:

                    DataRow[] rows = dt.Select("Item='"+ id + "'");
                    rows[0].Delete();

                    I'm guessing that the reference rows[0] isn't valid here. Perhaps dt.Select("Item='" + id + "'") isn't returning any rows? Check that. I would re-read the documentation on DataKeys and DataKeyField as well. Make sure you understand what they are there for. You want the DataKeyField to be a field with values that uniquely identify each row. Then you can use DataKeys[index] where index is the ItemIndex of the DataGridItem to give you a unique id for the datarow.

                    I Offline
                    I Offline
                    Ironsmith1977
                    wrote on last edited by
                    #9

                    Well that's just it I guess, none of the values that come into the DataGrid are unique for their row. For instance the seven columns are: Remove(checkbox), Brand, Color, Size, Material, Quantity, and Price. Sometimes all the columns are populated, sometimes they are not, it depends on the Item. With the exception of the Remove column, the other six columns could be several different values. I'll look into the DataKeyFields, though I do understand what you mean, I have no uniquely identifyable row. Take care, and you've been a great help! Ironsmith

                    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