65.9K
CodeProject is changing. Read more.
Home

Formatted vertical DataGrid web control

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.17/5 (3 votes)

Apr 20, 2006

CPOL

2 min read

viewsIcon

41082

downloadIcon

234

Quickly create a bound table, with column headers displayed vertically.

Introduction

In browsing around for a control to display data in a vertical fashion, I found a number of articles describing how to rotate the data, but none on how to create something with any formatting. Basically, several articles describe how to use the AutoGenerateColumns function of the DataGrid to allow the rows of a DataTable to be repeated horizontally instead of vertically. (A good example: Displaying vertical rows in a DataGrid.)

While this method works great for some instances, it really doesn't give much control over the formatting of the output. So, I made my first custom web control - the vertical grid. Due to the limitations of a DataGrid, I actually based it off the Table WebControl and created the table from scratch. This way, instead of just flipping the rows in the DataTable, it just renders the column data as rows in your HTML output.

Standard DataGrid

This is a very basic example.

Name Email Phone
Jack jack@joe.com 456-1234
Jill Jill@joe.com 123-4567
Jim Jim@joe.com 867-5309

Vertical DataGrid

Name Jack Jill Jim
Email jack@joe.com Jill@joe.com Jim@joe.com
Phone 456-1234 123-4567 867-5309

The Code

The key to the control is overriding the Render method for a table. Then, we can take the basic formatting for a table and add our own functionality to it. There are a lot more properties that I did not implement, but feel free to add to it. I primarily use CSS for all of my formatting, so that was the #1 priority for this. I also added the ability to do a raw style on the columns, but it's formatted just as you would for a CSS (style="element:value;"). This code would be included in a custom WebControl object which would inherit the System.Web.UI.WebControls.Table object.

Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
    'set up some temp variables
    Dim i, j As Int16
    Dim sTmp As String = ""

    'for each column in the dataset, we're going to make a row in the output
    For i = 0 To _DataSource.Columns.Count - 1
        _text &= vbTab & "<tr>" & vbCr
        'if the ShowHeader property is True then we're displaying the column names
        If _ShowHeader Then
            sTmp = ""
            'if the HeaderStyle is set, then include that in the td
            If _HeaderStyle <> "" Then
                sTmp = " style='" & _HeaderStyle & "'"
            End If
            'if the _HeaderCssClass is set, then include that in the td
            If _HeaderCssClass <> "" Then
                sTmp &= " class='" & _HeaderCssClass & "'"
            End If
            _text &= vbTab & vbTab & "<td" & sTmp & ">" & _
                     _DataSource.Columns(i).ColumnName & "</td>" & vbCr
        End If

        'then add each data item for that column to the table's row
        For j = 0 To _DataSource.Rows.Count - 1
            sTmp = ""
            'if the AltColumnCssClass is set 
            'and we're on an odd row, include it
            'otherwise, just use the standard CssClass if it's set
            If (_AltColumnStyle <> "" Or _
                   _AltColumnCssClass <> "") And j Mod 2 = 1 Then
                If _AltColumnStyle <> "" Then
                    sTmp = " style='" & _AltColumnStyle & "'"
                End If
                If _AltColumnCssClass <> "" Then
                    sTmp &= " class='" & _AltColumnCssClass & "'"
                End If
            Else
                If _ColumnStyle <> "" Then
                    sTmp = " style='" & _ColumnStyle & "'"
                End If
                If _ColumnCssClass <> "" Then
                    sTmp &= " class='" & _ColumnCssClass & "'"
                End If
            End If
            'put the data in there
            _text &= vbTab & vbTab & "<td" & sTmp & ">" & _
                     _DataSource.Rows(j).Item(i) & "</td>" & vbCr
        Next
        'close the row
        _text &= vbTab & "</tr>" & vbCr
    Next

    'then figure out the styles for the table as inherited by the table class
    sTmp = ""
    If Style.Count <> 0 Then
        Dim item As String
        For Each item In Style.Keys
            sTmp &= item & ":" & Style.Item(item) & ";"
        Next
        sTmp = " style=""" & sTmp & """"
    End If

    If CssClass <> "" Then
        sTmp &= " class='" & CssClass & "'"
    End If

    If BackColor.Name <> "" Then
        sTmp &= " bgcolor=""" & BackColor.Name & """"
    End If

    If BorderColor.Name <> "" Then
        sTmp &= " BorderColor=""" & BorderColor.Name & """"
    End If

    If Not IsDBNull(BorderWidth) Then
        sTmp &= " border=""" & BorderWidth.ToString & """"
    End If

    If Not IsDBNull(CellPadding) Then
        sTmp &= " CellPadding=""" & CellPadding.ToString & """"
    End If

    If Not IsDBNull(CellSpacing) Then
        sTmp &= " CellSpacing=""" & CellSpacing.ToString & """"
    End If

    'wrap the table tag around the rest of the HTML code
    _text = vbCr & "<table" & sTmp & ">" & vbCr & _text & "</table>" & vbCr
    'render the table
    output.Write([Text])
End Sub

Since I've included the DLL in the download, you can also just add the object to your Visual Studio .NET toolbox. After much toil and trouble, I found that to be the easiest way to add custom controls to your page.

Then, to bind your data and format the table the way you like, you can simply do something like this:

Dim dt As New DataTable()
dt = GetDBTable("SELECT * FROM tbl")
'replace this with whatever data you want

VerticalDataGrid1.DataSource = dt
'then you can set the style and such here if you like or on the HTML page

VerticalDataGrid1.ShowHeader = True
VerticalDataGrid1.HeaderStyle = "BACKGROUND-COLOR: SILVER;"
VerticalDataGrid1.BackColor = Color.White
VerticalDataGrid1.CellPadding = 2
VerticalDataGrid1.DataBind()

From there on out, it's up to you.