Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Advanced GridView question/issue 2

Status
Not open for further replies.

tperri

Programmer
Apr 8, 2006
728
US
Please help me if I'm being dense...

I'm building a datagrid by hand. The columns will represent Privilege's and the Rows represent FunctionID's.

Here is the Gridview HTML

Code:
                        <asp:GridView ID="grdSecurity" runat="server" AutoGenerateColumns="false" GridLines="None" OnRowDataBound="grdSecurity_RowDataBound" DataKeyNames="id">
                        <Columns>
                            <asp:BoundField DataField="name" HeaderText="Access" />
                            <asp:BoundField DataField="id" Visible="false" />
                        </Columns>
                        </asp:GridView> 
                        <table border="0" width="600">
                            <tr>
                                <td style="text-align:center;"><asp:Button ID="btnSaveSecurity" runat="server" 
                                        Text="Save" onclick="btnSaveSecurity_Click" /></td>
                            </tr>
                        </table>

I query my lookup tables to dynamically get their values so I can set values for a particular user. So, I add checkboxes to each cell... and read from the database and check boxes accordingly (This all is functional)

Code:
    protected void grdSecurity_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        //Add all checkboxes

        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            int iFunctionID = Convert.ToInt32(grdSecurity.DataKeys[e.Row.RowIndex].Value);

            for (int x = 0; x < dtPrivileges.Rows.Count; x++)
            {
                CheckBox chk = new CheckBox();
                chk.ID = "chk" + iFunctionID.ToString() + (x).ToString() ;
                e.Row.Cells[x + 2].Controls.Add(chk);
            }

            //Populate checkboxes

            for (int i = 0; i < dtPrivileges.Rows.Count; i++)
            {
                // If there is a functionID, privilegeID match, get a reference ot the checkbox and check it
                DataRow[] foundRows = dtUserPrivileges.Select("function_id=" + iFunctionID.ToString() + " and privilege_id=" + dtPrivileges.Rows[i]["id"].ToString() , "privilege_id asc");

                if (foundRows.Length > 0)
                {
                    CheckBox chkMe = (CheckBox)e.Row.Cells[i + 2].FindControl("chk" + iFunctionID.ToString() + (i).ToString());
                    chkMe.Checked = true;

                }

            }
        }

    }

Now, under my Gridview I have a "Save" button. When I click the Save button, I need to iterate through all of the checkboxes, add checked values to a DataTable so I can perform an Insert/Update off of these values. However, when I try to get reference to the Checkboxes I created, they are still null after I issue a FindControl to locate them in the row.

Do I need to gather the ID for the checkbox a different way? This GridView is on a master page, so the names for the checkboxes in the View Source are very obnoxious.

Here is the code that doesn't work...

Code:
   protected void btnSaveSecurity_Click(object sender, EventArgs e)
    {
        // Set up table to hold new settings
        
        DataTable dtSettings = new DataTable();
        dtSettings.Columns.Add("function_id");
        dtSettings.Columns.Add("privilege_id");

        foreach (GridViewRow grv in grdSecurity.Rows)
        {
            int iFunctionID = Convert.ToInt32(grdSecurity.DataKeys[grv.RowIndex].Value);

            for (int x = 0; x < dtPrivileges.Rows.Count; x++)
            {
                CheckBox chk = (CheckBox)grv.FindControl("chk" + iFunctionID.ToString() + (x).ToString());

                if (chk.Checked == true)
                {
                    // Add data to dtSettings
                    DataRow dr = dtSettings.NewRow();
                    dr["function_id"] = iFunctionID.ToString();
                    dr["privilege_id"] = x.ToString();
                    dtSettings.Rows.Add(dr);

                }
            }
        }

chk is always returning null, which shouldn't be the ase as I created the controls by hand up above. At my break point in the btnSaveSecurity where chk is, and grdSecurity has 21 rows, 9 columns, as I expect, so the controls must be there. I can not figure out how to properly name them in my FindControl method, or if I need to take a different approach?

Thanks for taking the time to look,
T
 
Why are you building the checboxes dynamically? I think is adding unnecessary problems. Just add a checkbox column to the gridview and bind the gridview to all possible permissions. Then query and get the permissions for the user. Then use your looping logic to set what permissons they have. I have done it this way in the past, and it works well.
 
I'm not exactly sure what you mean, jbenson.

What I'm trying to do is make a gridview to look like this


Add Save Delete
Project List X X X
Project Detail X X
.
.
.
.

From data is get from a table that looks like this
user_id function_id privilege_id
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2


(This sample data would describe the sample displaying above it)

So then I don't think I can hard code the privilege columns because they could change in the lookup table - that's why I'm adding dynmaically.

Do you see a way I can do what I need to do without doing it all in code?

Thanks for taking the time to look
T

 
Do you have a separate table (a reference or lookup table) that has all possible permissons for a user?
 
OK. I'm not sure of your complete db structure but you need to do somehting like this.

Bind your grid to show all possible permissions for whatever you like. (datatable 1 - checkboxes in template columns.)

Add Save Delete
Project List
Project Detail

Initally nothing is checked. This is just a shell.
Then get the permissions for the user (datatable 2)

Then loop through your reults (you can do this in the rowdatabound event of the grid) and check each checkbox as needed to get your reults.

Add Save Delete
Project List X X X
Project Detail X X
 
I ended up doing it this way, but with hard coding the columns. I couldn't get it to work dynamically creating columns. Thanks for your help, jbenson!
 
How would I get all checkboxes enabled if I do it this way? I don't want an Edit button on the rows.
 
You would create a template column with a checkbox in it. Then bind to your permissions table. From there you would loop through the permissions for the user and check the chekboxes as needed.
 
Those permissions columns need to be generated dynamically though. I tried to add Template columns in code to do this but could not get it to work (when I'd loop through the GridView when hitting a save button placed on the page, gridviewRow.FindControl("mycheckboxname") found nothing).

I want ensure if my client adds another type of permission in the permission lookup table that that change will be reflected in the GridView and that the app won't break. I currently have my app working with hard-coded template columns in the GridView. I'm trying to find out how to get it working right adding them in the code behind dynamically. I actually used the approach you described above before you posted and it works perfectly - if I declare the Template columns in the .aspx.

Thanks for your help so far :)
 
Can you post the structure of your table that holds ther permissions and also the values?
 
What you want is to be able to edit all rows and update at once?

 
yes, cesaru.

however the columns in the gridview need to be dynamically created, which is what i am having the problem when retrieving the values.
 
If the columns are dynamic, have you considered setting the AutoGenerateColumns property to True and then using the RowDataBound event to add the checkboxes to the relevant cells?


-------------------------------------------------------

Mark,
[URL unfurl="true"]http://aspnetlibrary.com[/url]
[URL unfurl="true"]http://mdssolutions.co.uk[/url] - Delivering professional ASP.NET solutions
[URL unfurl="true"]http://weblogs.asp.net/marksmith[/url]
 
Mark,

Can I do that and have the columns generate checkboxes that are enabled? I don't want to have to press and "edit" to enable a row. All rows of checkboxes are enabled after it is completely rendered.
 
Yes you can:
Code:
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
   e.Row.RowState = DataControlRowState.Edit
End Sub
 
Yes you can...have them enable in the rowdatabound.
How many columns with checkboxes do you have?
You can set up teh gridivew to autogenerate columns but also add the template column with a checkbox on it.

on rowdatabound you can hide\unhide the column if you want.
you can set the
checkbox1.checked = true.

use the link below for batch udpate.
 
ok Excellent, DataControlRowState is what I was looking for! Thanks :) Still kinda new to using the GridView :)
 
one more silly question - Will it autogerate a Checkbox if the data in a column is a certain type? Or *must* I go through RowDatabound?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top