【问题标题】:ASP.NET 2.0 - DataGrid with tbody / theadASP.NET 2.0 - 带有 tbody/thead 的 DataGrid
【发布时间】:2010-10-08 09:37:39
【问题描述】:

有没有办法让 DataGrid 控件呈现 tbody 和 thead HTML 元素?

【问题讨论】:

    标签: asp.net datagrid


    【解决方案1】:

    虽然我喜欢“user186197”的回答,但该博客文章使用反射,但在非完全受信任的托管环境中可能会出现问题。这是我们使用的,没有黑客:

    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);
        }
    }
    

    【讨论】:

    • 我喜欢这个解决方案,只是做了一些小改动:if (this.ShowHeader) table.Rows[0].TableSection = TableRowSection.TableHeader;if (this.ShowFooter) table.Rows[table.Rows.Count - 1].TableSection = TableRowSection.TableFooter;
    • @JohnAllers 我们如何在现有的 中使用这个类你能描述一下我吗..?
    • 虽然这个答案有效并且我非常感谢它,但正是这种东西让我对网络表单发疯并最终将我推向 MVC。
    • 我同意@JohnAllers 关于有条件地检查 ShowHeader 和 ShowFooter 是否为真的评论。
    • 我发现虽然我得到了THEAD,但我的THEAD 中仍然没有得到TH。有必要在我的控件的 OnLoad 事件中设置 UseAccessibleHeader = true 以使其工作。可能是我们的子类 DataGrid 的变幻莫测,所以YMMV
    【解决方案2】:

    也可以通过 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]); 
       }
    }
    

    那么你必须像这样在 body onload 上调用这个函数:

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

    来源:http://www.codeproject.com/KB/grid/HeaderOnEachPage.aspx

    【讨论】:

    • 一个javascript解决方案不错!
    【解决方案3】:

    DataGrid 没有内置的东西来满足您的需求。看看ASP.NET 2.0 CSS Friendly Control Adapters 1.0,他们已经内置了对 DataView 的支持,但似乎你可以很容易地为 DataGrid 采用这个想法。

    【讨论】:

    • 那是gridview,但不是datagrid。
    • 这只是一个想法。等效于“使用控制适配器”但带有示例。因为这个包是开源的。不多了。
    【解决方案4】:

    好吧,看起来数据网格不支持这个开箱即用,所以我不得不创建一个继承自 DataGrid 的类。在 DataGrid 呈现之后,我会解析 HTML 并将元素注入到正确的位置。

    附件是我的课程,供那些想知道如何操作的人使用。这是一种快速而肮脏的方法,因此欢迎我提出更好的想法。

    
    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
    

    【讨论】:

    • 抱歉,我不喜欢这个解决方案。例如,它取决于使用的 HtmlWriter。使用 UpperCaseHtmlWriter 您的解决方案将不起作用。也用 MemoryStream 编码...还有 HtmlTextWriter...
    • 您能进一步解释一下吗?控件的 Render 方法将 HtmlTextWriter 作为输入,它在定义中!您对 MemoryStream 等有什么异议?
    猜你喜欢
    • 2011-03-20
    • 2015-03-28
    • 2011-02-22
    • 2011-04-30
    • 2019-04-06
    • 2010-11-23
    • 2012-03-04
    • 2013-11-16
    • 2016-12-18
    相关资源
    最近更新 更多