What? No Columns in my GridView?
Well, lesson learned. the GridView is not infalliable.
So I am building another nightmare report that will sift through reams of data. This one has two Gridviews, one nested inside of the other. The point of the Gridview will be to display an asset and have the child gridview's rows display the locations where the asset exists. Aside from the entire table being a Pivot/Crosstab, and that I have to expect, on minimum, 100 assets to be returned for any search, I am also working with a custom data layer written for the project. So binding to these grids is, well, challenging.
To keep the amount of database traffic down, I only make two queries: One to get the asset list, and one to get all locations for those assets. Storing the locations in a datatable, I can use the datatable's 'Select' method to populate the subgrid. One problem we have is that the key field we 'Select' on, the ID of the asset, is already listed in the parent table, so I want to hide it.
<asp:TemplateField>
<ItemTemplate>
<td> <td colspan="5">
</asp:GridView runat="server" ID="SubViewContainer" CssClass="Grid"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>Here is the nested grid, inside a template field in the parent grid. On the RowDataBound event of the parent grid, I bind the child grid by extracting the control from the parent grid's columns. With the grid extracted, I can bind it individually.
GridView SubView = (GridView)e.Row.Cells[6].Controls[1];
DataRow[] SubData = WeeklySubData.Tables[0].Select("ID = '" + ID + "'");
DataTable Tbl = WeeklySubData.Tables[0].Clone();
foreach (DataRow D in SubData)
{
Tbl.ImportRow(D);
}
SubView.DataSource = Tbl;
SubView.DataBind();So this gets us our sub-data bound to the sub-grid. Great! Now let's hide the first column. That first column is only there so we can use the Select method, we don't need to display it. So let's just do
SubView.Columns[0].visible = false; , right?
Actually, no. For some reason, I don't have access to the Columns and that line would throw a runtime exception. The columns will have a Count of 0 and I can't do anything. So what's the solution?
Eventually I broke down and added an event handler to handle the 'OnRowCreated' event of the sub-grid. When this event fires, we're able to see the row we're in and hide the first cell of that row. I'm sure this is probably more expensive performance-wise; but it also works, which is the primary feature.
The event handler attachment code looks like
SubView.RowCreated += new GridViewRowEventHandler(SubView_RowCreated);
And the event handler looks like:
void SubView_RowCreated(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[0].Visible = false;
}Problem solved. now to explain to my boss what I've been doing all morning.