0%

【ASP】 動態新增GridView的 TemplateField欄位

因為某些搜尋條件的不同,造成要顯示的欄位可能也略有差異,一般可以透過多個GridView隱藏來隱藏去的方法,或是動態將某些Column隱藏起來,今天試的方法是在搜尋完後DataBind之前先將GridView的欄位換成自己想要的,新增一般BoundField沒什麼太特別的,但TemplateField就卡關了….參考很多資料後來做個筆記!!!

  • 先將該準備的類別與方法準備好
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    ''' <summary>
    ''' 複製控制項
    ''' </summary>
    ''' <param name="taget"></param>
    ''' <param name="source"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Clone(ByVal taget As Object, ByVal source As Object) As Object
    For Each p As System.Reflection.PropertyInfo In source.GetType().GetProperties()
    If p.CanRead AndAlso p.CanWrite Then
    p.SetValue(taget, p.GetValue(source, p.GetIndexParameters()), p.GetIndexParameters())
    End If
    Next
    Return taget
    End Function

    '新增一個類別實作ITemplate介面,就會跑出InstantiateIn的方法
    Public Class gvTemplate
    Implements ITemplate

    Private Property templateType As DataControlRowType
    Private Property columnName As String
    Private Property Control As Object
    Public Sub New(type As DataControlRowType, colname As String, ctrl As Object)
    templateType = type
    columnName = colname
    Control = ctrl
    End Sub

    Public Sub InstantiateIn(container As Control) Implements ITemplate.InstantiateIn
    Select Case templateType
    Case DataControlRowType.Header
    If Control Is Nothing Then
    '如果沒有沒有控制項,則塞入粗體字
    Dim lt As Literal = New Literal()
    lt.Text = "<B>" + columnName + "</B>"
    container.Controls.Add(lt)
    ElseIf TypeOf Control Is CheckBox Then
    '否則塞入控制項
    container.Controls.Add(Control)
    End If
    Case DataControlRowType.DataRow
    Dim obj As Object
    If Not Control Is Nothing Then
    Select Case Control.GetType().Name
    Case "CheckBox"
    obj = New CheckBox()

    '如果有傳入WebControl的話,複製一個新的並把它加到DataRow中
    '如果沒這麼做就直接將傳入的Control加入Container當中
    '會變成只有最後一行有那個Control(Control為Reference型別)
    SysHelper.Clone(obj, Control)
    End Select
    obj = SysHelper.Clone(obj, Control)
    Else
    obj = New Label()
    AddHandler CType(obj, Label).DataBinding, AddressOf data_DataBinding
    End If
    container.Controls.Add(obj)
    End Select
    End Sub

    Private Sub data_DataBinding(sender As Object, e As EventArgs)
    Dim lbl As Label = CType(sender, Label)
    Dim row As GridViewRow = CType(lbl.NamingContainer, GridViewRow)
    lbl.Text = DataBinder.Eval(row.DataItem, columnName).ToString()
    End Sub
    End Class
  • 使用方法如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Private Sub setGridViewColumns(ByVal mode As GriviewMode)
    gvSummons.Columns.Clear()
    '新增TemplateField的方法
    Dim TemplateField As TemplateField = New TemplateField()
    TemplateField.ItemStyle.HorizontalAlign = HorizontalAlign.Center
    Dim cb As CheckBox = New CheckBox()
    cb.ID = "cbSelectAll"
    cb.Text = "註記"
    cb.CssClass = "gvSummonsSelectAll"
    TemplateField.HeaderTemplate = New SysHelper.gvTemplate(DataControlRowType.Header, "", cb)

    cb = New CheckBox()
    cb.ID = "cbSelect"
    cb.CssClass = "gvSummonsSelect"
    TemplateField.ItemTemplate = New SysHelper.gvTemplate(DataControlRowType.DataRow, "", cb)
    gvSummons.Columns.Add(TemplateField)


    '新增BoundField的方法
    Dim BoundField As BoundField = New BoundField()
    BoundField.DataField = "voucherno"
    BoundField.HeaderText = "傳票號碼"
    BoundField.ItemStyle.HorizontalAlign = HorizontalAlign.Center
    gvSummons.Columns.Add(BoundField)
    End Sub