tags:

views:

1196

answers:

2

Hi,

I have a parent GridView that had a child GridView (code below), how do I get the value of the child gridview checkbox? And also, how do I save the state of the child gridview, i.e. if it is displayed or not? This is the function that is fired when the button is pressed that reads through the parent grid seeing which publications have been selected:

protected void DeleteSelectedProducts_Click(object sender, EventArgs e)
    {
        bool atLeastOneRowDeleted = false;

        // Iterate through the Products.Rows property
        foreach (GridViewRow row in GridView1.Rows)
        {
            // Access the CheckBox
            CheckBox cb = (CheckBox)row.FindControl("PublicationSelector");
            if (cb != null && cb.Checked)
            {
                // Delete row! (Well, not really...)
                atLeastOneRowDeleted = true;

                // First, get the ProductID for the selected row
                int productID =
                    Convert.ToInt32(GridView1.DataKeys[row.RowIndex].Value);

                // "Delete" the row
                DeleteResults.Text += string.Format(
                    "This would have deleted ProductID {0}<br />", productID);
                //DeleteResults.Text = "something";
            }


            // Show the Label if at least one row was deleted...
            DeleteResults.Visible = atLeastOneRowDeleted;
        }
    }

      <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"
        AutoGenerateColumns="False" DataKeyNames="PublicationID" 
        DataSourceID="ObjectDataSource1" Width="467px" OnRowDataBound="GridView1_RowDataBound"
        Font-Names="Verdana" Font-Size="Small">
        <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:CheckBox ID="PublicationSelector" runat="server" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="NameAbbrev" HeaderText="Publication Name" SortExpression="NameAbbrev" />
            <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
            <asp:BoundField DataField="State" HeaderText="State" SortExpression="State" />
            <asp:TemplateField HeaderText="Owners">
                <ItemTemplate>
                   <asp:Label ID="Owners" runat="server"></asp:Label>
                </ItemTemplate>
                <ItemStyle HorizontalAlign="Center" />
            </asp:TemplateField>
            <asp:BoundField DataField="Type" HeaderText="Type" SortExpression="Type" />
            <asp:TemplateField HeaderStyle-CssClass="hidden-column" ItemStyle-CssClass="hidden-column" FooterStyle-CssClass="hidden-column">
                <ItemTemplate>
                    <tr>
                        <td colspan="8" >
                            <div id="<%# Eval("PublicationID") %>" style="display: none; position: relative;" >
                                <asp:GridView ID="GridView2_ABPubs" runat="server" AutoGenerateColumns="false" Width="100%"
                                    DataKeyNames="PublicationID" Font-Names="Verdana" Font-Size="small">
                                    <Columns>
                                        <asp:TemplateField>
                                            <ItemTemplate>
                                                <asp:CheckBox ID="ChildPublicationSelector" runat="server" />
                                            </ItemTemplate>
                                        </asp:TemplateField>
                                        <asp:BoundField DataField="NameAbbrev" HeaderText="Publication Name" SortExpression="NameAbbrev" />
                                    </Columns>
                                </asp:GridView>
                            </div>
                        </td>
                    </tr>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetData"
        TypeName="shoom_dev._Default">
    </asp:ObjectDataSource>

    <p>
        <asp:Button ID="DeleteSelectedProducts" runat="server" 
            Text="Delete Selected Products" onclick="DeleteSelectedProducts_Click" />
    </p>

    <p>
        <asp:Label ID="DeleteResults" runat="server" EnableViewState="False" Visible="False"></asp:Label>
    </p>
+1  A: 

Do the same row.FindControl() method you have for the checkbox for the GridView2_ABPubs control. This should give you the gridview that you can then do a find control on.

However, having just spent three days staring and customizing a GridView your last template column with the child grid view doesn't need the and nodes, as these will be added automatically by the GridView control, that maybe making it trickier to find the child control.

I also found that the FindControl didn't look very far down the stack so I created an extension method to recursively hunt out the control:

public static T FindControl<T>(this Control parent, string controlName) where T: Control
{
    T found = parent.FindControl(controlName) as T;
    if (found != null)
       return found;

    foreach(Control childControl in parent.Controls)
    {
        found = childControl.FindControl<T>(controlName) as T;
        if (found != null)
           break;
    }

    return found;
}
David McEwing
Thank you I will give it a go. However, I don't understand this line "...However, having just spent three days staring and customizing a GridView your last template column with the child grid view doesn't need the and nodes, as these will be added automatically by the GridView control, that maybe making it trickier to find the child control." Which template can I remove?3 Days, this thing is driving me nuts!Thanks for your help, R.
flavour404
You need the template. You just don't need to include the TR and TD nodes in the itemtemplate layout of the last TemplateField
David McEwing
I am also new to C# and your helper function on the line parent.FindControl(controlName) as T return the error "Type parameter T cannot be used with the 'as' operator because it does not have a class type constraint nor a class constraint."Sorry, not trying to be a pain.
flavour404
Yes, I did take out the <td><tr> but the child gridview is displayed dynamically and it does not appear then.
flavour404
FindControl method updated. Sorry was typing from memory and forgot the `with T: class` in the declaration.
David McEwing
If it is not displaying the child grid then there is probably a problem with the code you are using to show it, as that should be operating on the div not the surrounding tr/td elements.
David McEwing
Erm, the find control method just lights up in red, with the with T: class underlined with ';' expected. Erm is T a class you have built?
flavour404
FindControl<T>() is an Extension method, you need to be in .NET3 or above and it needs to be in a public static class. It also uses Generics (.NET2 and above) so it can enforce you only get back the control type you expected.
David McEwing
David, can you look at the answer below where I have put your function with a class etc. I am in .net 3.0 and generics is enabled. Thanks R.
flavour404
A: 

David, is this correct:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;

public static class FindControl<T>
{public static T FindControl<T>(this Control parent, string controlName) where T : Control 
    { 
    T found = parent.FindControl(controlName) as T;
    if (found != null)
        return found; 
    foreach (Control childControl in parent.Controls)
    { found = childControl.FindControl(controlName) as T; 
        if (found != null)
            break; 
    } 
    return found; }

}

The class is saved as FindControl.cs. How do I call the function?

I'm feeling a little retarded, but in my defence this is the first time that I have used extendor classes.

Well I just got the error message that non-generic methods must be defined in a static class so I am guessing that I have some errors... lol

Thanks.

flavour404
change the class name to ControlExtensions and it should be fine. and add a closing } for the class and it should be fine.
David McEwing
Ok, after much reading about extendor methods I managed to get it working! I can finally get the value of a checkbox in each row of the child gridview. My next question is, unless the checkbox in the row of the parent gridview is checked, it doesn't pick up the value of the checkbox of the child gridview, why is that? And how would you pick up whether the child gridview is currently being shown?Thanks R.
flavour404