简体   繁体   中英

asp.net GridView table won't display if container div is set invisible during page load

I have two GridViews in an ASP WebForm project, one for display and one for edit. I have them each in a separate Div. I start with the Edit div invisible, and have a button in the display div that makes the display div invisible and the edit div visible. The basic code looks like this:

    <div id="DisplayDiv">
        <asp:GridView ID="CertList" runat="server" AutoGenerateColumns="False" DataSourceID="GetMyData">
            <Columns>
                <asp:BoundField DataField="a few datafields go here  />
            </Columns>
        </asp:GridView>
         <asp:Button ID="btnEdit" runat="server" OnClick="btnEdit_Click" Text="Edit" />
    </div>

    <div id="EditDiv" visible="false">
        <asp:GridView ID="CertList" runat="server" AutoGenerateColumns="False" DataSourceID="GetMyData" ">
            <Columns>
                <asp:BoundField DataField="a few datafields go here  />
            </Columns>
        </asp:GridView>
    </div>

The click event for the button looks like this:

    protected void btnEdit_Click(object sender, EventArgs e)
    {
        EditDiv.Visible = true;
        DisplayDiv.Visible = false;
    }

Everything works fine with the plumbing if I don't set the EditDiv's visible attribute to false in the markup. If I do set it to false, the table doesn't show when I set it back to true programmatically in the button click event. It seems that the DataView's rendering capability is tied to the ability to access the markup. So, based on that theory, I tried setting the position to absolute and the left to -10000 and I got the same result.

Is this just something I can't do, or am I missing something?

Edit: I put this test together at home and it works fine:

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">

<div id="Div1" runat="server">
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="CustomerID" DataSourceID="SqlDataSource1">
        <Columns>
            <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True" 
                SortExpression="CustomerID" />
            <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" 
                SortExpression="CompanyName" />
            <asp:BoundField DataField="ContactName" HeaderText="ContactName" 
                SortExpression="ContactName" />
            <asp:BoundField DataField="ContactTitle" HeaderText="ContactTitle" 
                SortExpression="ContactTitle" />
        </Columns>
    </asp:GridView>
    <asp:Button ID="Button1" runat="server" onclick="Button1_Click" 
        Text="Button1" />
</div>

<div id="Div2" runat="server" visible="false">
    <asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="ProductID" DataSourceID="SqlDataSource2">
        <Columns>
            <asp:BoundField DataField="ProductID" HeaderText="ProductID" 
                InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
            <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
                SortExpression="ProductName" />
            <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" 
                SortExpression="UnitsInStock" />
        </Columns>
    </asp:GridView>
    <asp:Button ID="Button2" runat="server" onclick="Button2_Click" 
        Text="Button2" />
</div>

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
    SelectCommand="SELECT TOP (5) CustomerID, CompanyName, ContactName, ContactTitle FROM Customers">
</asp:SqlDataSource>

<asp:SqlDataSource ID="SqlDataSource2" runat="server" 
    ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
    SelectCommand="SELECT TOP (5) * FROM Products">
</asp:SqlDataSource>

</asp:Content>

And the code behind:

    protected void Button1_Click(object sender, EventArgs e)
    {
        Div1.Visible = false;
        Div2.Visible = true;
    }

    protected void Button2_Click(object sender, EventArgs e)
    {
        Div2.Visible = false;
        Div1.Visible = true;
    }

So there's a proof of concept. It's probably a silly mistake, but I'll post it once I find out what the story is.

Set runat="server" for both the divs then try to access from the code behind.

<div id="DisplayDiv" runat="server">
   ....
</div>

<div id="EditDiv" runat="server" visible="false">
   ....
</div>

Or you can use a asp:Panel instead of a div then you can access the Visible property from code behind.

<asp:Panel Id ="PnlDisplay" runat="server">
     ....
</asp:Panel>

<asp:Panel Id ="PnlEdit" runat="server" Visible="false">
     ....
</asp:Panel>

And you code behind

protected void btnEdit_Click(object sender, EventArgs e)
{
     PnlDisplay.Visible = false;
     PnlEdit.Visible = true;
}

The problem turned out to be due to a strange idea I had in the SQLDataSource. The markup looks like this (Note: there is no ID in the table with a value of 0, that's a dummy value):

<asp:SqlDataSource ID="foo" runat="server" 
    ConnectionString="<%$ ConnectionStrings:BlahBlah %>" 
    SelectCommand="SELECT blahblahblabbertyblah from blah
                    WHERE ID = '0'>
</asp:SqlDataSource>

And then my code behind has this little masterpiece:

    protected void btnEdit_Click(object sender, EventArgs e)
    {
        DisplayDiv.Visible = false;
        EditDiv.Visible = true; 
        string SqlSelect =
            "SELECT c.CourseCode AS [Course Code], c.Description, ce.CertDate AS [Date Certified], ce.Recert, " +
            "DATEADD(m, c.Period, ce.CertDate) AS [Expiration Date], e.DocLink, e.CertifiedTrainer, e.GroupLeader " +
            "FROM Certifications c " +
            "INNER JOIN CertificationEmployees ce ON c.ID = ce.CertID " +
            "RIGHT JOIN Employees e ON ce.EmpID = e.ID " +
            "WHERE e.ID = '" + EmployeeList.SelectedValue + "' " +
            "ORDER BY [Course Code]";
        EditCertifications.SelectCommand = 
            "SELECT blahblahblabbertyblah from blah " +
            "WHERE e.ID = '" + aListImUsing.SelectedValue + "' " +
        DataView eView = (DataView)EditCertifications.Select(DataSourceSelectArguments.Empty);
        eTable = eView.ToTable();
        //use the eView table to set various onscreen values
    }

As it turned out, every time I did anything that required a screen change, the GridView mysteriously disappeared. I added a CommandField column to the GridView, and when I clicked on the Edit button, I'd lose the GridView. Turned out that the GridView was null. I was thinking that if I respecified the SelectCommand programmatically, it would persist. It doesn't; it reverts back to the one specified in the markup as soon as wherever you've specified it in code goes out of scope.

The fix was to change the dummy value in the WHERE clause to a parameter as I'm supposed to do, and tie the parameter to the current value in the dropdown list that I'm using. I changed the WHERE clause to this:

    WHERE e.ID = @EmpID

and added this:

    <SelectParameters>
        <asp:ControlParameter ControlID="EmployeeList" Name="EmpID" PropertyName="SelectedValue" />
    </SelectParameters>

And my GridViews magically appeared.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM