Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
I created a custom gridview control that allows the user to group together similar values. So say you had a list of customers from different states and you wanted to list the customers by state. My gridview would go through the data, find rows with new state values, create a dynamic row and insert it above the current row. So :
 
Alabama
Bob Jonson 123 Main street
Fred Newber 533 Oak Street
Arizona
Dick James 555 Ledge Hill
Jane Smith 123 Park St
 
I initially create the dynamic rows in an override of the OnRowDataBound event. Then I re-create the rows on postback in an override of the OnRowCreated event. The code works great.
THE PROBLEM shows up when I try to add other controls to the gridview. So say I create a template column with a "New order from this customer" button in front of their name. When I click the button, nothing happens. When I click it again, the RowCommand event fires.
 
I've narrowed the problem down but have been unable to solve it. The ID's generated for the buttons in the template column CHANGE on postback. So when the data is bound, the control id will be "ctl00_ContentPlaceHolder1_ExtraGridView1_ctl04_LinkButton1". But on postback the id changes to "ctl00_ContentPlaceHolder1_ExtraGridView1_ctl07_LinkButton1". After the initial postback the ID no longer changes.
 
Something is happening on postback that doesn't happen when the data is bound but I can't seem to figure it out. Here is the code I'm using:
 
Imports Microsoft.VisualBasic
Imports System.ComponentModel
Imports System.Data
Imports kExchangeWebControls
 
Namespace CallCenter
    Public Class GroupByGrid
        Inherits GridView
 
        Dim lastcat As String = ""
 
        <Browsable(True), DefaultValue(GetType(String), "")> _
        Public Property GroupByColumnName() As String
            Get
                Return ViewState("GROUPCOLUMN")
            End Get
            Set(ByVal value As String)
                ViewState("GROUPCOLUMN") = value
            End Set
        End Property
 
        <Browsable(True), DefaultValue(GetType(String), "{0}")> _
        Public Property GroupByFormatString() As String
            Get
                If ViewState("GROUPBYFORMAT") Is Nothing Then
                    Return "{0}"
                Else
                    Return ViewState("GROUPBYFORMAT")
                End If
            End Get
            Set(ByVal value As String)
                ViewState("GROUPBYFORMAT") = value
            End Set
        End Property
 
        <Browsable(True), DefaultValue(GetType(String), "Uncategorized")> _
        Public Property GroupByUncategorizedName() As String
            Get
                If ViewState("GROUPBYUNAME") Is Nothing Then
                    Return "Uncategorized"
                Else
                    Return ViewState("GROUPBYUNAME")
                End If
            End Get
            Set(ByVal value As String)
                ViewState("GROUPBYUNAME") = value
            End Set
        End Property
 
        Dim GroupStyle As Style
 
        <Browsable(True), Category("Appearance"), Description(""), PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(True)> _
        Public ReadOnly Property GroupByCellStyle() As Style
            Get
                If GroupStyle Is Nothing Then
                    GroupStyle = New Style()
                End If
                Return GroupStyle
            End Get
        End Property
 
        Protected Overrides Sub OnRowCreated(ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
            MyBase.OnRowCreated(e)
 
            If Not rebind Then
                If Not Me.DesignMode Then
                    If e.Row.RowType = DataControlRowType.DataRow Then
                        If GroupByColumnName IsNot Nothing Then
                            If GroupByColumnName.Trim <> "" Then
 
                                'Since this fires before the viewstate is loaded, load the category
                                Dim thiscat As String = System.Web.HttpContext.Current.Server.UrlDecode(System.Web.HttpContext.Current.Request.Form(Me.ID & "_ROW" & e.Row.RowIndex))
 
                                If thiscat IsNot Nothing Then
                                    If lastcat.ToUpper.Trim <> thiscat.ToUpper.Trim Then
                                        Dim gvr As New GridViewRow(e.Row.RowIndex, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
                                        Dim c As New TableCell
 
                                        c.ApplyStyle(GroupByCellStyle)
 
                                        Dim l As New LiteralControl
 
                                        If thiscat.Trim <> "" Then
                                            l.Text = thiscat
                                        Else
                                            l.Text = GroupByUncategorizedName
                                            lastcat = l.Text
                                        End If
 
                                        l.Text &= "<input type=""hidden"" name=""" & Me.ID & "_ROW" & e.Row.RowIndex & """ value=""" & System.Web.HttpContext.Current.Server.UrlEncode(thiscat) & """/>"
                                        c.ColumnSpan = e.Row.Cells.Count
                                        c.Controls.Add(l)
 
                                        gvr.Cells.Add(c)
                                        Dim tbl As Table = Me.Controls(0)
                                        Dim gvrcpy = e.Row
                                        tbl.Rows.Remove(e.Row)
                                        tbl.Rows.Add(gvr)
                                        tbl.Rows.Add(gvrcpy)
                                        lastcat = thiscat
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
 
            End If
 

 
        End Sub
 

 
        Protected Overrides Sub OnRowDataBound(ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
            MyBase.OnRowDataBound(e)
 

 
            If e.Row.RowType = DataControlRowType.DataRow Then
                If Not Me.DesignMode Then
                    If GroupByColumnName IsNot Nothing Then
                        If GroupByColumnName.Trim <> "" Then
                            'For now, only DataViews/tables are valid data sources
                            Dim drv As DataRowView = e.Row.DataItem
 
                            If drv IsNot Nothing Then
                                'Get the current category field
                                Dim thiscat As String = dev(GroupByFormatString).toString()
 

                                'IF the categories do not match, add a new grouping row
                                If lastcat.ToUpper.Trim <> thiscat.ToUpper.Trim Then
                                    Dim gvr As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
                                    Dim c As New TableCell
 
                                    c.ApplyStyle(GroupByCellStyle)
 
                                    If thiscat.Trim <> "" Then
                                        c.Text = thiscat
                                    Else
                                        c.Text = GroupByUncategorizedName
                                        lastcat = c.Text
                                    End If
 
                                    'Store this category in a hidden field that can be accessed during control creation.
                                    c.Text &= "<input type=""hidden"" name=""" & Me.ID & "_ROW" & e.Row.RowIndex & """ value=""" & System.Web.HttpContext.Current.Server.UrlEncode(thiscat) & """/>"
 
                                    c.ColumnSpan = e.Row.Cells.Count
 
                                    gvr.Cells.Add(c)
                                    Dim tbl As Table = Me.Controls(0)
                                    tbl.Rows.AddAt(tbl.Rows.GetRowIndex(e.Row), gvr)
                                    lastcat = thiscat
                                End If
                            End If
                        End If
                    End If
                End If
            End If
 
        End Sub
 

 
        Private rebind As Boolean = False
 
        Private Sub ExtraGridView_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DataBinding
 
            rebind = True
        End Sub
 

    End Class
End Namespace
 
Thanks in advance for any help you can offer!
Posted 14-Jun-11 10:37am

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Maciej Los 315
1 OriginalGriff 273
2 Aajmot Sk 224
3 Marcin Kozub 210
4 Richard MacCutchan 200
0 OriginalGriff 7,853
1 Sergey Alexandrovich Kryukov 7,107
2 DamithSL 5,604
3 Manas Bhardwaj 4,986
4 Maciej Los 4,790


Advertise | Privacy | Mobile
Web02 | 2.8.1411023.1 | Last Updated 14 Jun 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100