The outer grid represents a session table of a user and each session contains a few transaction logs associated with the outer sessionId. The .aspx is straightforward: a TemplateField column is used to embed the inner GridView.
<asp:GridView ID="gvSession" CssClass="datagrid" runat="server" AllowPaging="True" PageSize="6" AutoGenerateColumns="False" DataSourceID="ldsSession" OnRowDataBound="gvSession_RowDataBound" Width="680px"> <Columns> <asp:BoundField DataField="StaffName" HeaderText="Staff Name" /> <asp:BoundField DataField="SessionId" HeaderText="Session Id" /> <asp:BoundField DataField="SessionStartTime" HeaderText="Session Start Time" /> <asp:BoundField DataField="SessionDuration" HeaderText="Session Duration" /> <asp:TemplateField HeaderText="Tx Logs"> <ItemTemplate > <asp:GridView ID="gvTxLog" runat="server" DataSourceID="ldsTxLog" AutoGenerateColumns="False" Width="100%"> <Columns> <asp:BoundField DataField="TxType" HeaderText="Tx Type" ItemStyle-Width="70%" /> <asp:BoundField DataField="Duration" HeaderText="Duration" /> </Columns> </asp:GridView> <asp:ObjectDataSource ID="ldsTxLog" runat="server" SelectMethod="GetTxLogs" TypeName="DAO.ReportDAO"> <SelectParameters> <asp:ControlParameter ControlID="txtStartDate" Name="start" PropertyName="Text" Type="String" /> <asp:ControlParameter ControlID="txtEndDate" Name="end" PropertyName="Text" Type="String" /> <asp:ControlParameter ControlID="ddlStaffs" Name="staffId" PropertyName="SelectedValue" Type="Int32" /> <asp:Parameter Name="sessionId" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> <asp:ObjectDataSource ID="ldsSession" runat="server" SelectMethod="GetSessions" TypeName="DAO.ReportDAO"> <SelectParameters> <asp:ControlParameter ControlID="txtStartDate" Name="start" PropertyName="Text" /> <asp:ControlParameter ControlID="txtEndDate" Name="end" PropertyName="Text" /> <asp:ControlParameter ControlID="ddlStaffs" Name="staffId" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource>
To make it simple, the outer grid just uses declarative data binding. While the inner grid, although appears to be the same, has to be initialized manually because, like I mentioned earlier, it relies on the sessionId from the outer grid after outer's data binding. So here is the trick:
protected void gvSession_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType .DataRow) { ObjectDataSource s = (ObjectDataSource )e.Row.FindControl("ldsTxLog" ); s.SelectParameters["sessionId" ].DefaultValue = e.Row.Cells[1].Text; GridView subView = (GridView )e.Row.FindControl("gvTxLog" ); subView.DataBind(); } }
This resolution is not perfect though, because you have to use 2 separate data sources, one for each GridView. And that brings the N+1 problem. But there is a better solution coming...
No comments:
Post a Comment