十幾行程式碼搞定 Master-Detail GridView(內含子 GridView)
0

摘要

在網路上看到很多 GridView 內含子 GridView 的範例,雖然方法不同不過程式碼都有點小複雜,想說難道沒有更簡單易懂的方法嗎?
在此文章中將用十幾行的程式碼,就教你快速學會並搞定這種 Master-Detail GridView 的需求。

程式碼實作

我們以 Northwind 資料庫為例,首先在頁面上放置二組 GridView+SqlDataSoruce,分別繫結至 [Orders] 、[Order Details] 這二個資料表。

我們先來看一下它的程式碼及執行結果,後續再做進一步的詳細說明。
我們只要在 GridView 的 RowDataBound 事件撰寫下面十幾行的程式碼就完成了,不要懷疑這已經是全部的程式碼。

1 Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound     
2 2     If (e.Row.RowState And DataControlRowState.Selected) = DataControlRowState.Selected Then    
3 3         Dim oRow As New GridViewRow(0, -1, DataControlRowType.DataRow, e.Row.RowType)     
4 4         GridView2.Visible = True    
5 5         GridView2.DataBind()     
6 6         Dim sHTML As String = Bee.Web.WebFunc.ControlToHTML(GridView2)     
7 7         GridView2.Visible = False    
8 8         Dim oCell As New TableCell     
9 9         oCell.Text = sHTML     
10 10         oCell.ColumnSpan = e.Row.Cells.Count     
11 11         oRow.Cells.Add(oCell)     
12 12         e.Row.Parent.Controls.AddAt(e.Row.RowIndex + 2, oRow)     
13 13     End If    
開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound 2 If (e.Row.RowState And DataControlRowState.Selected) = DataControlRowState.Selected Then 3 Dim oRow As New GridViewRow(0, -1, DataControlRowType.DataRow, e.Row.RowType) 4 GridView2.Visible = True 5 GridView2.DataBind() 6 Dim sHTML As String = Bee.Web.WebFunc.ControlToHTML(GridView2) 7 GridView2.Visible = False 8 Dim oCell As New TableCell 9 oCell.Text = sHTML 10 oCell.ColumnSpan = e.Row.Cells.Count 11 oRow.Cells.Add(oCell) 12 e.Row.Parent.Controls.AddAt(e.Row.RowIndex + 2, oRow) 13 End If

執行程式,選取 GridView 的某一資料列,就會展開其子 GridView 。執行換頁動作,一樣可以正常展開子 GridView。

接下來說明這個範例的一些細節,Master GridView 繫結 [Orders] 資料表,設定 DataKeyNames="OrderID",當選取某筆資料時,GridView 的 SelectedValue 就是該筆資料的 OrderID 欄位值。另外設定 GridView 的 EnableViewState="False",這個設定主要是讓 GridView 選取時都會重新做 DataBind 的動作。

1 <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"    
2 2     DataKeyNames=
"OrderID" DataSourceID="SqlDataSource1" EmptyDataText="沒有資料錄可顯示。"     3 3     ForeColor="#333333" GridLines="None" AllowPaging="True" EnableViewState="False">     " originalcode=" ">開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4" 2 DataKeyNames="OrderID" DataSourceID="SqlDataSource1" EmptyDataText="沒有資料錄可顯示。" 3 ForeColor="#333333" GridLines="None" AllowPaging="True" EnableViewState="False">

再來就是 Detail GridView 繫結 [Order Details] 資料表,一樣設定 GridView 的 EnableViewState="False",且設定 Visible="False",也就是初始狀態 Detail GridView 是隱藏的。

1 <asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" BackColor="LightGoldenrodYellow"    
2 2     BorderColor="Tan" BorderWidth="1px" CellPadding="2" DataKeyNames="OrderID,ProductID"    
3 3     DataSourceID="SqlDataSource2" EmptyDataText="沒有資料錄可顯示。" ForeColor="Black" GridLines="None" Visible="False" EnableViewState="False">    
4  view plain | print | copy to clipboard | ?   
view plain | print | copy to clipboard | ? " originalcode=" view plain | print | copy to clipboard | ? ">開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" BackColor="LightGoldenrodYellow" 2 BorderColor="Tan" BorderWidth="1px" CellPadding="2" DataKeyNames="OrderID,ProductID" 3 DataSourceID="SqlDataSource2" EmptyDataText="沒有資料錄可顯示。" ForeColor="Black" GridLines="None" Visible="False" EnableViewState="False"> view plain | print | copy to clipboard | ?

Detail GridView 所繫結的 SqlDataSource 控制項,將其 SelectParameters 的 @OrderID 參數關連至 Master GridView 的 SelectedValue。

1 <SelectParameters>    
2 2     <asp:ControlParameter ControlID="GridView1" Name="OrderID" PropertyName="SelectedValue"    
3 3         Type="Int32" />    
4 4 </SelectParameters>    
4 " originalcode=" 2 4 ">開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?
<SelectParameters> 2 <asp:ControlParameter ControlID="GridView1" Name="OrderID" PropertyName="SelectedValue" 3 Type="Int32" /> 4 </SelectParameters>

再來還有一個重要步驟,就是在 aspx 程式碼中,要設定 Page 的 EnableEventValidation="false",因為我們動態將 Detail GridView Render 出來插入 Master GridView 中,整個控制項階層都被異動,這樣會造成事件驗證失敗。

1 <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default5.aspx.vb" Inherits="Default5" EnableEventValidation="false" %>  
" originalcode=" ">開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default5.aspx.vb" Inherits="Default5" EnableEventValidation="false" %>

另外在 Master GridView 的 RowDataBound 事件中,有一個 ControlToHTML 方法是取得 Detail GridView 的 HTML 碼,這個方法可以參考筆者另一篇「使用 BasePage 來解決 GridView 執行 RenderControl 產生的錯誤」文章有詳細說明。

1 Dim sHTML As String = Bee.Web.WebFunc.ControlToHTML(GridView2)  
開新視窗(view plain) | 列印(print) | 複製(copy to clipboard) | ?
Dim sHTML As String = Bee.Web.WebFunc.ControlToHTML(GridView2)
 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 ◕‿◕ Abigale 的頭像
    ◕‿◕ Abigale

    ◕‿◕ Abigale的部落格

    ◕‿◕ Abigale 發表在 痞客邦 留言(0) 人氣()