Forth.NETVisual Basic 8 (2005)DBAWebFormsVisual Studio 2005ADO.NETArchitect.NET 2.0C# 2.0C# 3.0IntermediateDevVisual StudioWindows.NETVisual BasicASP.NETC#
交叉制表报告:动态向网格添加列





2.00/5 (5投票s)
2007年9月10日
2分钟阅读

39729

529
文章描述了如何在运行时动态地向网格添加列。
引言
我们很多人可能已经使用网格在 asp .net 中显示报表。 通常,当我们在网格中显示报表时,列数将是固定的。 可以在报表中出现的行可能取决于很多因素。 交叉表报表是指行以及列数将根据用户提供的条件而变化的报表。 因此,当您使用网格显示这些类型的报表时,您必须动态地构建列。
背景
为了更清楚地解释,让我们用一个例子来演示。 在这里,你有一个简单的数据库,其中在不同的系有 'n' 个学生在一个表中,他们的分数在另一个表中。 当我说他们来自不同的系时,我的意思是他们学习的科目数量也会不同。 假设系 1 有 2 个科目,系 2 有 1 个科目。 因此,在系 1 学生的成绩单中,你可以看到科目 1 和科目 2 的分数。 而在系 2 学生的成绩单中,你只能看到一个科目的分数。
使用代码
让我们看看如何构建我们的业务对象。 我们需要一个“科目”业务对象来保存他的分数,以及一个“学生”业务对象,包含他的名字和分数列表。 它可以像这样:
因此,为了填充对象,我们需要先填充学生的数据,然后创建科目的对象并将其添加到分数列表的列表中。 对于交叉表实现,我们可以将此对象作为网格的数据源。 然后在绑定之前,我们可以动态地添加需要的列。
对于绑定字段,我们可以直接分配它的标题文本和数据字段。
Private Function GetBoundColumn(ByVal hText As String, ByVal datafield As String) As BoundField Dim newColumn As BoundField newColumn = New BoundField() With newColumn .HeaderText = hText .DataField = datafield End With Return newColumn End Function
对于模板列,我们需要使用一个实现 ITemplate 接口的类。
Private Function GetTemplateColumn(ByVal dSource As List(Of Types), ByVal colId As Integer) As TemplateField Dim newColumn As TemplateField newColumn = New TemplateField() With newColumn .HeaderTemplate = New TemplateFactory("M" & colId, DataControlRowType.Header, 0) .ItemTemplate = New TemplateFactory("", DataControlRowType.DataRow, colId) End With Return newColumn End Function Public Class TemplateFactory Implements ITemplate Dim _hdrName As String Dim _rowType As DataControlRowType Dim _colId As Integer Public Sub New(ByVal hdrName As String, ByVal rowType As DataControlRowType, ByVal colId As Integer) _hdrName = hdrName _rowType = rowType _colId = colId End Sub Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn If (_rowType = DataControlRowType.Header) Then Dim oLabel As New Label() oLabel.Text = _hdrName oLabel.ForeColor = Drawing.Color.White container.Controls.Add(oLabel) ElseIf (_rowType = DataControlRowType.DataRow) Then Dim oTextBox As New TextBox() oTextBox.ID = _colId AddHandler oTextBox.DataBinding, AddressOf TextBox1_DataBinding container.Controls.Add(oTextBox) End If End Sub Protected Sub TextBox1_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs) Dim txt As TextBox Dim gvRow As GridViewRow Dim i As Integer txt = CType(sender, TextBox) gvRow = CType(txt.NamingContainer, GridViewRow) i = CType(txt.ID, Integer) If (CType(gvRow.DataItem, TypesList).TypeList.Count > i) Then txt.Text = DataBinder.Eval(CType(gvRow.DataItem, TypesList).TypeList(i), "Name") End If End Sub End Class
关注点
如果我们有很多报表需要交叉表实现,那么我们可以采用“Builder”设计模式来简化实现。 有关这方面的更多详细信息可以在附件中找到。
历史
在此处保持您所做的任何更改或改进的实时更新。