透過公用Function使GridView能夠進行RowSpan(行合併)

使用GridView一陣子後,應該或多或少會遇到這樣的需求,就是某些重複出現的Row希望能夠做RowSpan的合併動作,網路上要找這樣的解決方式應該還蠻容易的。不過既然是可能經常會用到的東西,不如把她抽出來寫成公用的Function,未來需要的時候,呼叫該Function直接處理就好

使用GridView一陣子後,應該或多或少會遇到這樣的需求,就是某些重複出現的Row希望能夠做RowSpan的合併動作,網路上要找這樣的解決方式應該還蠻容易的。不過既然是可能經常會用到的東西,不如把她抽出來寫成公用的Function,未來需要的時候,呼叫該Function直接處理就好

我們以北風資料庫的Order Details為例子,選出前50筆,然後希望相同的OrderId能夠合併在一起。

本來的樣子

GVRS01

合併之後

GVRS02

先準備好公用的類別



Public Class objPublic

    Public Sub GVRowSpan(ByVal Parent As System.Web.UI.Control, ByVal GridVewName As String, ByVal RowIndex() As Integer, ByVal SelfColor As Boolean, ByVal myColors As System.Drawing.Color())
        Dim mySingleRow As GridViewRow
        Dim tmpS As String = "" '用於存放RowSpan的文字
        Dim tmpI As Integer     '用於RowSpan的RowIndex
        'Dim Gv As GridView = CType(Me.FindControl(GridVewName), GridView)
        Dim Gv As GridView = CType(Me.FindControlEx(Parent, GridVewName), GridView)
        Dim ColorCnt As Integer = myColors.Length
        Dim ColorIdx As Integer = 0
        Dim y As Integer

        If Gv IsNot Nothing Then

            For Each mySingleRow In Gv.Rows

                '從Rowindex>0開始做
                If mySingleRow.RowIndex = 0 Then
                    tmpS = mySingleRow.Cells(RowIndex(0)).Text.Trim()
                    For y = 0 To RowIndex.Count - 1
                        mySingleRow.Cells(RowIndex(y)).RowSpan = 1
                    Next
                    tmpI = 0
                    If SelfColor Then
                        mySingleRow.BackColor = myColors(ColorIdx Mod ColorCnt)
                    End If
                End If
                If mySingleRow.RowIndex > 0 Then
                    '判斷本筆資料是否與要合併資料一致
                    If mySingleRow.Cells(RowIndex(0)).Text.Trim() = tmpS Then
                        '要合併
                        For y = 0 To RowIndex.Count - 1
                            '合併的Row的RowSpan+1
                            Gv.Rows(tmpI).Cells(RowIndex(y)).RowSpan += 1
                            '被合併的這一個Row,Visiable=False
                            mySingleRow.Cells(RowIndex(y)).Visible = False
                        Next
                        If SelfColor Then
                            mySingleRow.BackColor = myColors(ColorIdx Mod ColorCnt)
                        End If
                    Else
                        '不需合併

                        '設定下次檢查的內容
                        tmpS = mySingleRow.Cells(RowIndex(0)).Text.Trim()
                        For y = 0 To RowIndex.Count - 1
                            '設定該Row的RowSpan=1
                            mySingleRow.Cells(RowIndex(y)).RowSpan = 1
                        Next
                        '設定下次要處理RowSpan的index
                        tmpI = mySingleRow.RowIndex
                        If SelfColor Then
                            ColorIdx += 1
                            mySingleRow.BackColor = myColors(ColorIdx Mod ColorCnt)
                        End If
                    End If
                End If
            Next
        End If
    End Sub

    Public Function FindControlEx(ByVal Parent As System.Web.UI.Control, ByVal ID As String) As System.Web.UI.Control
        Dim oCtrl As System.Web.UI.Control = Nothing
        Dim oChildCtrl As System.Web.UI.Control = Nothing

        '先使用 FindControl 去尋找指定的子控制項 
        oCtrl = Parent.FindControl(ID)

        '若尋找不到則往下層遞迴方式去尋找()
        If oCtrl Is Nothing Then
            For Each oChildCtrl In Parent.Controls
                '以遞迴方式呼叫原函式
                oCtrl = FindControlEx(oChildCtrl, ID)
                '若有尋找到指定控制項則離開迴圈
                If oCtrl IsNot Nothing Then Exit For
            Next
        End If

        Return oCtrl
    End Function

End Class

然後準備測試的畫面


        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
            CellPadding="4" DataKeyNames="OrderID,ProductID" DataSourceID="SqlDataSource1" 
            EmptyDataText="沒有資料錄可顯示。" ForeColor="#333333" GridLines="None">
            <RowStyle BackColor="#E3EAEB" />
            <Columns>
                <asp:BoundField DataField="OrderID" HeaderText="OrderID" ReadOnly="True" 
                    SortExpression="OrderID" />
                <asp:BoundField DataField="ProductID" HeaderText="ProductID" ReadOnly="True" 
                    SortExpression="ProductID" />
                <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
                    SortExpression="UnitPrice" />
                <asp:BoundField DataField="Quantity" HeaderText="Quantity" 
                    SortExpression="Quantity" />
                <asp:BoundField DataField="Discount" HeaderText="Discount" 
                    SortExpression="Discount" />
            </Columns>
            <FooterStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#666666" ForeColor="White" HorizontalAlign="Center" />
            <SelectedRowStyle BackColor="#C5BBAF" Font-Bold="True" ForeColor="#333333" />
            <HeaderStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" />
            <EditRowStyle BackColor="#7C6F57" />
            <AlternatingRowStyle BackColor="White" />
        </asp:GridView>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
            ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString1 %>" 
            ProviderName="<%$ ConnectionStrings:NorthwindConnectionString1.ProviderName %>" 
            SelectCommand="SELECT TOP 50 [OrderID], [ProductID], [UnitPrice], [Quantity], [Discount] FROM [Order Details]" >
        </asp:SqlDataSource>
    
    </div>

使用的方式很簡單,在GridView的PreRender事件中,呼叫該Class的Function並傳遞適當的參數


        Dim SelfColor As Boolean = True
        Dim Color1 As System.Drawing.Color = System.Drawing.Color.FromArgb(216, 216, 255)
        Dim Color2 As System.Drawing.Color = System.Drawing.Color.FromArgb(255, 251, 158)
        Dim Colors(1) As System.Drawing.Color
        Colors(0) = Color1
        Colors(1) = Color2


        Dim oPub As New objPublic
        Dim RowIndex(0) As Integer
        RowIndex(0) = 0
        Dim GridViewName As String = "GridView1"
        oPub.GVRowSpan(Page, GridViewName, RowIndex, SelfColor, Colors)

    End Sub

這樣就可以囉

^_^


以下是簽名:


Microsoft MVP
Visual Studio and Development Technologies
(2005~2019/6) 
topcat
Blog:http://www.dotblogs.com.tw/topcat