ASP.NET 2.0 - DataGrid with tbody / thead

て烟熏妆下的殇ゞ 提交于 2020-01-01 09:59:22

问题


Is there a way to get the DataGrid control to render the tbody and thead HTML elements?


回答1:


While I like the answer by "user186197", that blog post uses reflection, things might go wrong in non-full-trusted hosting environments. Here's what we use, no hacks:

public class THeadDataGrid : System.Web.UI.WebControls.DataGrid
{
    protected override void OnPreRender(EventArgs e)
    {
        this.UseAccessibleHeader = true; //to make sure we render TH, not TD

        Table table = Controls[0] as Table;

        if (table != null && table.Rows.Count > 0)
        {
            table.Rows[0].TableSection = TableRowSection.TableHeader;
            table.Rows[table.Rows.Count - 1].TableSection = TableRowSection.TableFooter;
        }

        base.OnPreRender(e);
    }
}



回答2:


It can be done also via javascript.

function AddTHEAD(tableName)
{
   var table = document.getElementById(tableName); 
   if(table != null) 
   {
    var head = document.createElement("THEAD");
    head.style.display = "table-header-group";
    head.appendChild(table.rows[0]);
    table.insertBefore(head, table.childNodes[0]); 
   }
}

Then you must call this function on body onload like that:

<body onload="javascript: AddTHEAD('DataGridId')">

Source: http://www.codeproject.com/KB/grid/HeaderOnEachPage.aspx




回答3:


DataGrid does not have something built-in to accomplish your needs. Take a look on ASP.NET 2.0 CSS Friendly Control Adapters 1.0 they are have built-in support for DataView, but seems you can easily adopt this idea for DataGrid.




回答4:


Right, looks like the data grid doesn't support this out of the box, so I've had to create a class that inherits from the DataGrid. After the DataGrid has rendered I then parse the HTML and inject the elements in the correct place.

Attached is my class for those that whant to know how. This is a quick and dirty approach, so I'm welcome to better ideas.


Imports System.IO
Imports System.Text

Public Class TestDataGrid
  Inherits System.Web.UI.WebControls.DataGrid

  Private sTHeadClass As String = String.Empty
  Private sTBodyClass As String = String.Empty
  Private sTFootClass As String = String.Empty

#Region " Properties "

  Public Property THeadClass() As String
    Get
      Return sTHeadClass
    End Get
    Set(ByVal value As String)
      sTHeadClass = value
    End Set
  End Property

  Public Property TBodyClass() As String
    Get
      Return sTBodyClass
    End Get
    Set(ByVal value As String)
      sTBodyClass = value
    End Set
  End Property

  Public Property TFootClass() As String
    Get
      Return sTFootClass
    End Get
    Set(ByVal value As String)
      sTFootClass = value
    End Set
  End Property

#End Region

  Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

    Dim oMemoryStream As New MemoryStream()
    Dim oStreamWriter As New StreamWriter(oMemoryStream)
    Dim oStreamReader As New StreamReader(oMemoryStream)
    Dim oHtmlTextWriter As New HtmlTextWriter(oStreamWriter)

    MyBase.Render(oHtmlTextWriter)

    oHtmlTextWriter.Flush()

    oMemoryStream.Flush()
    oMemoryStream.Position = 0

    Dim sHtml As String = oStreamReader.ReadToEnd()
    Dim oHtml As New Text.StringBuilder()

    Dim iPastIndex As Integer = 0
    Dim iIndex As Integer = sHtml.IndexOf("<tr>")

    oHtml.Append(sHtml.Substring(iPastIndex, iIndex - iPastIndex))

    iPastIndex = iIndex

    If ShowHeader Then
      WriteElementStart(oHtml, "thead", sTHeadClass)

      'Write Header Row
      iIndex = sHtml.IndexOf("</tr>", iPastIndex) + 5
      oHtml.Append(sHtml.Substring(iPastIndex, iIndex - iPastIndex))
      iPastIndex = iIndex

      oHtml.Append("</thead>")
      WriteElementStart(oHtml, "tbody", sTBodyClass)
    Else
      WriteElementStart(oHtml, "tbody", sTBodyClass)
    End If

    If ShowFooter Then

      'Writer Body Rows
      iIndex = sHtml.LastIndexOf("<tr>")
      oHtml.Append(sHtml.Substring(iPastIndex, iIndex - iPastIndex))
      iPastIndex = iIndex

      WriteElementEnd(oHtml, "tbody")
      WriteElementStart(oHtml, "tfoot", sTFootClass)

      'Write Footer Row
      iIndex = sHtml.LastIndexOf("</table>")
      oHtml.Append(sHtml.Substring(iPastIndex, iIndex - iPastIndex))
      iPastIndex = iIndex

      WriteElementEnd(oHtml, "tfoot")

    Else
      iIndex = sHtml.LastIndexOf("</table>")
      oHtml.Append(sHtml.Substring(iPastIndex, iIndex - iPastIndex))
      iPastIndex = iIndex

      WriteElementEnd(oHtml, "tbody")
    End If

    oHtml.Append(sHtml.Substring(iPastIndex, sHtml.Length - iPastIndex))

    writer.Write(oHtml.ToString())
  End Sub

  Private Sub WriteElementStart(ByVal Builder As StringBuilder, ByVal Tag As String, ByVal CssClass As String)
    If String.IsNullOrEmpty(CssClass) Then
      Builder.AppendFormat("<{0}>", Tag)
    Else
      Builder.AppendFormat("<{0} class='{1}'>", Tag, CssClass)
    End If
  End Sub

  Private Sub WriteElementEnd(ByVal Builder As StringBuilder, ByVal Tag As String)
    Builder.AppendFormat("</{0}>", Tag)
  End Sub

End Class


来源:https://stackoverflow.com/questions/562010/asp-net-2-0-datagrid-with-tbody-thead

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!