With the ASP.NET GridView control, how can I disable controls or individual cells in a GridViewRow after PageIndexChanged?

StackOverflow https://stackoverflow.com/questions/3963603

Question

I have a data bound GridView control, in which I am able to disable individual cells based on the User role. This only works on the first page.

private void LimitAccessToGridFields()
    {
        if (User.IsInRole("Processing")) return;

        foreach (GridViewRow gridViewRow in gvScrubbed.Rows)
        {
            var checkBox = ((CheckBox) gridViewRow.FindControl("cbScrubbed"));
            checkBox.Enabled = false;

            // ButtonField does not have an ID to FindControl with
            // Must use hard-coded Cell index
            gridViewRow.Cells[1].Enabled = false; 
        }
    }

I call this method on Page_Load, where it works. I've tried it in the PageIndexChaging and PageIndexChanged event handlers, where it doesn't work. While debugging, it appears to successfully set Enabled to false in both of the controls in the row. My goal is to disable these fields, depending on user role, after changing the page. How should this be accomplished?

Was it helpful?

Solution 2

I found that this must be done in the RowDataBound event handler.

if (e.Row.RowType == DataControlRowType.DataRow)
{
   // details elided ...

   // Limits the access to grid fields.
   if (!User.IsInRole("PROCESSING"))
   {
       cbstuff.Enabled = false; // a checkbox
       e.Row.Cells[1].Enabled = false; //a link button
   }
}

OTHER TIPS

You do not need to iterate through any controls to disable or hide/visible them.

Every cell in a GridView control is actually a HTML table reference, when rendered (look at the code in your page using FireFly or Inspector).

So why not iterate through all the cells, and any controls found within each cell, just disable them? Or you can simply loop through each row of your GridView and disable or hide it directly, which will affect everything inside the row.

Hiding using a Table Cell reference example:

foreach (GridViewRow gRow in myGridView.Rows)
            {
                if (gRow.RowType == DataControlRowType.DataRow)
                {
                        TableCellCollection tbcCol = (TableCellCollection)gRow.Cells;
                        foreach (TableCell tblCell in tbcCol)
                                tblCell.Enabled = false;
                }
            }

So that will disable everything table cell by table cell.

OR.. why not just disable the entire row?

foreach (GridViewRow gRow in myGridView.Rows)
            {
                if (gRow.RowType == DataControlRowType.DataRow)
                   gRow.Enable = false;
            }

If you need to pin-point or filter particular control types (CheckBox, TextBox, Label, etc) and only affect those controls then simply test for them!

foreach (GridViewRow gRow in myGridView.Rows)
{
  if (gRow.RowType == DataControlRowType.DataRow)
  {
     TableCellCollection tbcCol = (TableCellCollection)gRow.Cells;
     foreach (TableCell tblCell in tbcCol)
         if (((TextBox)tblCell) != null)
             ((TextBox)tblCell).Enable = false;
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top