You may have used Master and Detail Gridview to show selected row data in detail Gridview. But what if you have to click on selected cell in one Gridview which happen to result filtered result set in another Gridview.
I will be using two Gridview, AJAX, and a tiny client side JavaScript for this requirement. I will further modify the previous example and add new controls for this requirement. Here is the new code which is self explanatory
WebForm1.aspx
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm1.aspx.vb" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test Multi Header Gridview</title>
<div id="Div1" runat="server">
<script language="javascript" type="text/javascript">
function ShowGrid(type, value) {
document.getElementById("<%=txtType.ClientID%>").value = type;
document.getElementById("<%=txtValue.ClientID%>").value = value;
document.getElementById("dataInfo").innerHTML = "Selection Type:" + type + ", Value: " + value;
document.getElementById("<%=btnShowData.ClientID%>").click();
}
</script>
</div>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div id="searchArea" align="center">
<asp:Button ID="btnGetData" runat="server" Text="Get Data" />
<br />
Export Format
<asp:DropDownList ID="ddlExportData" runat="server" CssClass="clsCombo" >
<asp:ListItem Value="CSV" Text="CSV"/>
<asp:ListItem Value="XLS" Text="Excel"/>
<asp:ListItem Value="XML" Text="XML"/>
</asp:DropDownList>
<asp:Button ID="btnExportData" runat="server" CausesValidation="false" Text="Export Data" />
<div style="width:0;height:0;display:none;visibility:hidden;">
<asp:TextBox ID="txtType" runat="server" Width="0" Height="0" />
<asp:TextBox ID="txtValue" runat="server" Width="0" Height="0" />
<asp:Button ID="btnShowData" runat="server" Width="0" Height="0" />
</div>
</div>
<div align="center">
<asp:GridView ID="gvwRecord" runat="server" AutoGenerateColumns="false" FooterStyle-Wrap="false"
EmptyDataText="No data is available for this search criteria." DataKeyNames="ID" AllowPaging="false" >
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-HorizontalAlign="left"/>
<asp:BoundField DataField="Name" HeaderText="Name" ItemStyle-HorizontalAlign="left" ItemStyle-Wrap="false" />
<asp:TemplateField HeaderText="Age" ItemStyle-HorizontalAlign="Right" HeaderStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:HyperLink ID="hplAge" NavigateUrl="#" runat="server" Text='<%# Eval("Age")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Sex" ItemStyle-HorizontalAlign="Right" HeaderStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:HyperLink ID="hplSex" NavigateUrl="#" runat="server" Text='<%# Eval("Sex")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Title" HeaderText="Title" ItemStyle-Wrap="false"/>
</Columns>
</asp:GridView>
<br /><br />
<b id="dataInfo"></b> <br />
<asp:UpdatePanel ID="UpdatePanelX" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gvwRecordDetail" runat="server" AutoGenerateColumns="false" FooterStyle-Wrap="false"
EmptyDataText="No data is available" DataKeyNames="ID" AllowPaging="false" >
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-HorizontalAlign="left"/>
<asp:BoundField DataField="Name" HeaderText="Name" ItemStyle-HorizontalAlign="left" ItemStyle-Wrap="false" />
<asp:BoundField DataField="Title" HeaderText="Title" ItemStyle-Wrap="false"/>
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnShowData" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
WebForm1.aspx.vb
Public Class WebForm1
Inherits System.Web.UI.Page
#Region "Main GridView"
Protected Sub btnGetData_Click(sender As Object, e As EventArgs) Handles btnGetData.Click
Dim tst As New TestRecord
Dim recs As List(Of TestRecord) = tst.LoadData
Session("Data") = recs
gvwRecord.DataSource = recs
gvwRecord.DataBind()
gvwRecordDetail.Visible = False
End Sub
Private Sub gvwRecord_RowCreated(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvwRecord.RowCreated
If e.Row.RowType = DataControlRowType.Header Then
Dim headerCell1 As TableCell = New TableCell()
Dim headerCell2 As TableCell = New TableCell()
headerCell1.ColumnSpan = 3
headerCell1.Text = "Main Header 1"
headerCell1.BackColor = Drawing.Color.LightGray
headerCell1.HorizontalAlign = HorizontalAlign.Center
headerCell2.ColumnSpan = 2
headerCell2.Text = "Main Header 2"
headerCell2.BackColor = Drawing.Color.LightGray
headerCell2.HorizontalAlign = HorizontalAlign.Center
Dim rowHeader1 As GridViewRow = New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal)
rowHeader1.Cells.Add(headerCell1)
rowHeader1.Cells.Add(headerCell2)
rowHeader1.ForeColor = Drawing.Color.Black
rowHeader1.Font.Bold = True
rowHeader1.Visible = True
gvwRecord.Controls(0).Controls.AddAt(0, rowHeader1)
Dim fields2 As TableCellCollection = e.Row.Cells
Dim headerCell11 As TableCell = New TableCell()
Dim headerCell12 As TableCell = New TableCell()
headerCell11.ColumnSpan = 2
headerCell11.Text = "ID and Name"
headerCell11.BackColor = Drawing.Color.Maroon
headerCell12.ColumnSpan = 3
headerCell12.Text = "Age and Sex"
headerCell12.BackColor = Drawing.Color.Maroon
Dim rowHeader2 As GridViewRow = New GridViewRow(1, 1, DataControlRowType.Header, DataControlRowState.Normal)
rowHeader2.Cells.Add(headerCell11)
rowHeader2.Cells.Add(headerCell12)
rowHeader2.Font.Size = 12
rowHeader2.ForeColor = Drawing.Color.White
rowHeader2.HorizontalAlign = HorizontalAlign.Center
rowHeader2.Visible = True
rowHeader2.Font.Bold = True
gvwRecord.Controls(0).Controls.AddAt(1, rowHeader2)
ElseIf e.Row.RowType = DataControlRowType.Footer Then
Dim footerCell1 As TableCell = New TableCell()
Dim footerCell2 As TableCell = New TableCell()
Dim footerCell3 As TableCell = New TableCell()
Dim footerCell4 As TableCell = New TableCell()
Dim dataRecs As List(Of TestRecord) = Nothing
Dim totalRec As Integer = 0
Dim totalMale As Integer = 0
Dim totalFemale As Integer = 0
Dim totalAgeBelow30 As Integer = 0
Dim totalAgeAbove30 As Integer = 0
If Session("Data") IsNot Nothing Then
dataRecs = DirectCast(Session("Data"), List(Of TestRecord))
If Not dataRecs Is Nothing AndAlso dataRecs.Count > 0 Then
totalRec = dataRecs.Count
Dim list1 = From r As TestRecord In dataRecs Where r.Sex = "Male"
totalMale = list1.Count
Dim list2 = From r As TestRecord In dataRecs Where r.Sex = "Female"
totalFemale = list2.Count
Dim list3 = From r As TestRecord In dataRecs Where r.Age < 30
totalAgeBelow30 = list3.Count
Dim list4 = From r As TestRecord In dataRecs Where r.Age >= 30
totalAgeAbove30 = list4.Count
End If
End If
footerCell1.Text = "Summary"
footerCell2.Text = "Age [< 30yrs: " & totalAgeBelow30.ToString() & "] [>=30yrs:" & totalAgeAbove30.ToString() & "]"
footerCell3.ColumnSpan = 2
footerCell3.Text = "Male: " & totalMale.ToString() & " Female:" & totalFemale.ToString()
footerCell4.Text = "Total Count:" & totalRec.ToString()
Dim rowFooter1 As GridViewRow = New GridViewRow(gvwRecord.Rows.Count + 3, 0, DataControlRowType.Footer, DataControlRowState.Normal)
rowFooter1.Cells.Add(footerCell1)
rowFooter1.Cells.Add(footerCell2)
rowFooter1.Cells.Add(footerCell3)
rowFooter1.Cells.Add(footerCell4)
rowFooter1.ForeColor = Drawing.Color.Black
rowFooter1.BackColor = Drawing.Color.LightGray
rowFooter1.HorizontalAlign = HorizontalAlign.Left
rowFooter1.Font.Bold = True
rowFooter1.Visible = True
For cellCount As Integer = 0 To rowFooter1.Cells.Count - 1
rowFooter1.Cells(cellCount).Wrap = False
Next
gvwRecord.Controls(0).Controls.AddAt(gvwRecord.Rows.Count + 3, rowFooter1)
End If
End Sub
Private Sub gvwRecord_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvwRecord.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim paramString As String = ""
Dim value As String = ""
value = CType(e.Row.Cells(2).FindControl("hplAge"), HyperLink).Text
paramString = "javascript:ShowGrid('Age'," & value & ");"
CType(e.Row.Cells(2).FindControl("hplAge"), HyperLink).Attributes.Add("onclick", paramString)
value = CType(e.Row.Cells(3).FindControl("hplSex"), HyperLink).Text
paramString = "javascript:ShowGrid('Sex','" & value & "');"
CType(e.Row.Cells(3).FindControl("hplSex"), HyperLink).Attributes.Add("onclick", paramString)
End If
End Sub
Private Sub btnShowData_Click(sender As Object, e As System.EventArgs) Handles btnShowData.Click
Dim typeName As String = Me.txtType.Text
Dim value As String = Me.txtValue.Text
Dim testRecs As List(Of TestRecord) = Nothing
Dim filteredRecs As List(Of TestRecord) = Nothing
testRecs = DirectCast(Session("Data"), List(Of TestRecord))
If typeName = "Age" Then
Dim recList = From r As TestRecord In testRecs Where r.Age = CInt(value)
filteredRecs = recList.ToList
ElseIf typeName = "Sex" Then
Dim recList = From r As TestRecord In testRecs Where r.Sex.Equals(value)
filteredRecs = recList.ToList
End If
Me.gvwRecordDetail.Visible = True
Me.gvwRecordDetail.DataSource = filteredRecs
Me.gvwRecordDetail.DataBind()
End Sub
#End Region
#Region "Exports"
Private Sub btnExportData_Click(sender As Object, e As System.EventArgs) Handles btnExportData.Click
If Me.gvwRecord.Rows.Count > 0 Then
Select Case Me.ddlExportData.SelectedItem.Value.ToUpper()
Case "CSV"
ExportDataToCSV()
Case "XLS"
ExportDataToExcel()
Case "XML"
ExportToXML()
End Select
Else
Response.Write("No Data available for export")
End If
End Sub
Private Sub ExportDataToCSV()
Dim fileName As String = "FileName_" & Format(Now, "yyyyMMddhhmms") & ".csv"
Dim localGridView As GridView = GetLocalMktSourceSummaryGridView()
If localGridView IsNot Nothing AndAlso localGridView.Rows.Count < 65536 Then
HttpContext.Current.Response.Clear()
' Set the response headers to fit our CSV file
HttpContext.Current.Response.ContentType = "text/plain"
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" & fileName)
Using writer As New System.IO.StreamWriter(HttpContext.Current.Response.OutputStream)
Dim columnHeader As String = String.Empty
For i As Integer = 0 To localGridView.Columns.Count - 1
columnHeader += localGridView.Columns(i).HeaderText & IIf(i < localGridView.Columns.Count - 1, ",", "").ToString()
Next
writer.WriteLine(columnHeader)
'writer.WriteLine(AddCSVHeaderRow()) ' Only if you need custom headers to be added
' Add all the data rows
For Each row As GridViewRow In localGridView.Rows
writer.WriteLine(GetCSVLine(row.Cells))
Next
End Using
' End the current response. Otherwise, excel will open with the whole page inside.
HttpContext.Current.Response.End()
Else
Response.Write("Too many rows - Export to Excel not possible")
End If
End Sub
Private Function GetLocalMktSourceSummaryGridView() As GridView
Dim rptData As List(Of TestRecord) = Nothing
Dim localGridView As New GridView
If Session("Data") IsNot Nothing Then rptData = DirectCast(Session("Data"), List(Of TestRecord))
localGridView.AllowPaging = False
localGridView.AllowSorting = False
localGridView.AutoGenerateColumns = False
localGridView.DataSource = rptData
Dim col01