ASP.NET 2.0 - 带有 tbody/thead 的 DataGrid

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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 等有什么异议?

以上是关于ASP.NET 2.0 - 带有 tbody/thead 的 DataGrid的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET Core 2.0 中使用带有身份模型的 Azure Active Directory OAuth

如何在现有数据库中实现 ASP.NET Identity 2.0?

ASP.NET Core 2.0 中RequiredAttribute 的本地化

ASP.NET Core 2.0 MVC 6. 如何管理每个视图的javascript文件?

ASP.Net Core 2.0 - 如何从中间件返回自定义 json 或 xml 响应?

如何在 Visual Studio 2017 Web Proj ASP.NET Core 2.0 中禁用 Https