Click here to Skip to main content
15,892,005 members
Articles / Web Development / ASP.NET

Edit Individual GridView Cells in ASP.NET

Rate me:
Please Sign up or sign in to vote.
4.88/5 (84 votes)
14 Nov 2009CPOL5 min read 1.4M   26.3K   305  
Edit individual GridView cells without putting the entire row into edit mode.Examples using the SqlDataSource and ObjectDataSource controls are included.
#Region "Directives"

Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls

#End Region

Partial Public Class GridViewEditCell2VB
    Inherits System.Web.UI.Page

    ''' <summary> 
    ''' There is a ButtonField column and the Id column 
    ''' therefore first edit cell index is 2 
    ''' </summary> 
    Private Const _firstEditCellIndex As Integer = 2

#Region "Page Load"

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        If Not IsPostBack Then
            _sampleData = Nothing
            Me.GridView1.DataSource = _sampleData
            Me.GridView1.DataBind()
        End If

        If Me.GridView1.SelectedIndex > -1 Then
            ' Call UpdateRow on every postback 
            Me.GridView1.UpdateRow(Me.GridView1.SelectedIndex, False)
        End If
    End Sub

#End Region

#Region "GridView1"

    Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
        If e.Row.RowType = DataControlRowType.DataRow Then
            ' Get the LinkButton control in the first cell 
            Dim _singleClickButton As LinkButton = DirectCast(e.Row.Cells(0).Controls(0), LinkButton)
            ' Get the javascript which is assigned to this LinkButton 
            Dim _jsSingle As String = ClientScript.GetPostBackClientHyperlink(_singleClickButton, "")

            ' If the page contains validator controls then call 
            ' Page_ClientValidate before allowing a cell to be edited 
            _jsSingle = _jsSingle.Insert(11, "if(typeof Page_ClientValidate != 'function' || Page_ClientValidate())")

            ' Add events to each editable cell 
            For columnIndex As Integer = _firstEditCellIndex To e.Row.Cells.Count - 1
                ' Add the column index as the event argument parameter 
                Dim js As String = _jsSingle.Insert(_jsSingle.Length - 2, columnIndex.ToString())
                ' Add this javascript to the onclick Attribute of the cell 
                e.Row.Cells(columnIndex).Attributes("onclick") = js
                ' Add a cursor style to the cells 
                e.Row.Cells(columnIndex).Attributes("style") += "cursor:pointer;cursor:hand;"
            Next
        End If
    End Sub

    Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
        Dim _gridView As GridView = DirectCast(sender, GridView)

        Select Case e.CommandName
            Case ("SingleClick")
                ' Get the row index 
                Dim _rowIndex As Integer = Integer.Parse(e.CommandArgument.ToString())
                ' Parse the event argument (added in RowDataBound) to get the selected column index 
                Dim _columnIndex As Integer = Integer.Parse(Request.Form("__EVENTARGUMENT"))
                ' Set the Gridview selected index 
                _gridView.SelectedIndex = _rowIndex
                ' Bind the Gridview 
                _gridView.DataSource = _sampleData
                _gridView.DataBind()

                ' Write out a history if the event 
                Me.Message.Text += ("Single clicked GridView row at index " & _rowIndex.ToString() & " on column index ") & _columnIndex & "<br />"

                ' Get the display control for the selected cell and make it invisible 
                Dim _displayControl As Control = _gridView.Rows(_rowIndex).Cells(_columnIndex).Controls(1)
                _displayControl.Visible = False
                ' Get the edit control for the selected cell and make it visible 
                Dim _editControl As Control = _gridView.Rows(_rowIndex).Cells(_columnIndex).Controls(3)
                _editControl.Visible = True
                ' Get the validator control for the selected cell if it exists and make it visible 
                If _gridView.Rows(_rowIndex).Cells(_columnIndex).Controls.Count > 5 Then
                    Dim _validatorControl As Control = _gridView.Rows(_rowIndex).Cells(_columnIndex).Controls(5)
                    _validatorControl.Visible = True
                End If

                ' Clear the attributes from the selected cell to remove the click event 
                _gridView.Rows(_rowIndex).Cells(_columnIndex).Attributes.Clear()

                ' Set focus on the selected edit control 
                ScriptManager.RegisterStartupScript(Me, [GetType](), "SetFocus", "document.getElementById('" & _editControl.ClientID & "').focus();", True)
                ' If the edit control is a dropdownlist set the 
                ' SelectedValue to the value of the display control 
                If TypeOf _editControl Is DropDownList AndAlso TypeOf _displayControl Is Label Then
                    DirectCast(_editControl, DropDownList).SelectedValue = DirectCast(_displayControl, Label).Text
                End If
                ' If the edit control is a textbox then select the text 
                If TypeOf _editControl Is TextBox Then
                    DirectCast(_editControl, TextBox).Attributes.Add("onfocus", "this.select()")
                End If
                ' If the edit control is a checkbox set the 
                ' Checked value to the value of the display control 
                If TypeOf _editControl Is CheckBox AndAlso TypeOf _displayControl Is Label Then
                    DirectCast(_editControl, CheckBox).Checked = Boolean.Parse(DirectCast(_displayControl, Label).Text)
                End If

                Exit Select
        End Select
    End Sub

    ''' <summary> 
    ''' Update the sample data 
    ''' </summary> 
    ''' <param name="sender"></param> 
    ''' <param name="e"></param> 
    Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs)
        Dim _gridView As GridView = DirectCast(sender, GridView)

        If e.RowIndex > -1 Then
            ' Loop though the columns to find a cell in edit mode 
            For i As Integer = _firstEditCellIndex To _gridView.Columns.Count - 1
                ' Get the editing control for the cell 
                Dim _editControl As Control = _gridView.Rows(e.RowIndex).Cells(i).Controls(3)
                If _editControl.Visible Then
                    Dim _dataTableColumnIndex As Integer = i - 1

                    Try
                        ' Get the id of the row 
                        Dim idLabel As Label = DirectCast(_gridView.Rows(e.RowIndex).FindControl("IdLabel"), Label)
                        Dim id As Integer = Integer.Parse(idLabel.Text)
                        ' Get the value of the edit control and update the DataTable 
                        Dim dt As DataTable = _sampleData
                        Dim dr As DataRow = dt.Rows.Find(id)
                        dr.BeginEdit()
                        If TypeOf _editControl Is TextBox Then
                            dr(_dataTableColumnIndex) = DirectCast(_editControl, TextBox).Text
                        ElseIf TypeOf _editControl Is DropDownList Then
                            dr(_dataTableColumnIndex) = DirectCast(_editControl, DropDownList).SelectedValue
                        ElseIf TypeOf _editControl Is CheckBox Then
                            dr(_dataTableColumnIndex) = DirectCast(_editControl, CheckBox).Checked
                        End If
                        dr.EndEdit()

                        ' Save the updated DataTable 
                        _sampleData = dt

                        ' Clear the selected index to prevent 
                        ' another update on the next postback 
                        _gridView.SelectedIndex = -1

                        ' Repopulate the GridView 
                        _gridView.DataSource = dt
                        _gridView.DataBind()
                    Catch generatedExceptionName As ArgumentException
                        Me.Message.Text += "Error updating GridView row at index " & e.RowIndex & "<br />"

                        ' Repopulate the GridView 
                        _gridView.DataSource = _sampleData
                        _gridView.DataBind()
                    End Try
                End If
            Next
        End If
    End Sub

    Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
        Dim _gridView As GridView = DirectCast(sender, GridView)

        ' Set the PageIndex to the NewPageIndex 
        _gridView.PageIndex = e.NewPageIndex

        ' Repopulate the GridView 
        _gridView.DataSource = _sampleData
        _gridView.DataBind()
    End Sub

    Protected Sub GridView1_Sorting(ByVal sender As Object, ByVal e As GridViewSortEventArgs)
        Dim _gridView As GridView = DirectCast(sender, GridView)

        ' Alternate the sort direction 
        Dim sortDirection__1 As String = "ASC"
        If GridView1SortDirection = SortDirection.Ascending Then
            sortDirection__1 = "ASC"
            GridView1SortDirection = SortDirection.Descending
        Else
            sortDirection__1 = "DESC"
            GridView1SortDirection = SortDirection.Ascending
        End If

        ' Set the SortExpression and SortDirection 
        Dim _sampleDataView As DataView = _sampleData.DefaultView
        _sampleDataView.Sort = (e.SortExpression & " ") + sortDirection__1

        ' Repopulate the GridView 
        _gridView.DataSource = _sampleDataView
        _gridView.DataBind()
    End Sub

    ''' <summary> 
    ''' Property to maintain Gridview sort direction in viewstate 
    ''' </summary> 
    Public Property GridView1SortDirection() As SortDirection
        Get
            If ViewState("GridView1SortDirection") Is Nothing Then
                ViewState("GridView1SortDirection") = SortDirection.Ascending
            End If

            Return DirectCast(ViewState("GridView1SortDirection"), SortDirection)
        End Get
        Set(ByVal value As SortDirection)
            ViewState("GridView1SortDirection") = value
        End Set
    End Property

#End Region

#Region "Render Override"

    ' Register the dynamically created client scripts 
    Protected Overloads Overrides Sub Render(ByVal writer As HtmlTextWriter)
        ' The client events for GridView1 were created in GridView1_RowDataBound 
        For Each r As GridViewRow In GridView1.Rows
            If r.RowType = DataControlRowType.DataRow Then
                For columnIndex As Integer = _firstEditCellIndex To r.Cells.Count - 1
                    Page.ClientScript.RegisterForEventValidation(r.UniqueID & "$ctl00", columnIndex.ToString())
                Next
            End If
        Next

        MyBase.Render(writer)
    End Sub

#End Region

#Region "Sample Data"

    ''' <summary> 
    ''' Property to manage data 
    ''' </summary> 
    Private Property _sampleData() As DataTable
        Get
            Dim dt As DataTable = DirectCast(Session("TestData"), DataTable)

            If dt Is Nothing Then
                ' Create a DataTable and save it to session 
                dt = New DataTable()

                dt.Columns.Add(New DataColumn("Id", GetType(Integer)))
                dt.Columns.Add(New DataColumn("Description", GetType(String)))
                dt.Columns.Add(New DataColumn("AssignedTo", GetType(String)))
                dt.Columns.Add(New DataColumn("Status", GetType(String)))
                dt.Columns.Add(New DataColumn("Tick", GetType(String)))

                dt.Rows.Add(New Object() {1, "Create a new project", "Declan", "Complete", True})
                dt.Rows.Add(New Object() {2, "Build a demo applcation", "Olive", "In Progress", False})
                dt.Rows.Add(New Object() {3, "Test the demo applcation", "Peter", "Pending", True})
                dt.Rows.Add(New Object() {4, "Deploy the demo applcation", "", "", False})
                dt.Rows.Add(New Object() {5, "Support the demo applcation", "Lorna", "Pending", False})
                dt.Rows.Add(New Object() {6, "Build v2 of demo applcation", "Andy", "Pending", True})
                dt.Rows.Add(New Object() {7, "Test v2 of demo applcation", "Peter", "Pending", False})
                dt.Rows.Add(New Object() {8, "Deploy v2 the demo applcation", "Matt", "Pending", True})

                ' Add the id column as a primary key 
                Dim keys As DataColumn() = New DataColumn(0) {}
                keys(0) = dt.Columns("id")
                dt.PrimaryKey = keys

                _sampleData = dt
            End If

            Return dt
        End Get

        Set(ByVal value As DataTable)
            Session("TestData") = value
        End Set
    End Property

#End Region

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Chief Technology Officer
Ireland Ireland
I have been designing and developing business solutions for the aviation, financial services, healthcare and telecommunications industries since 1999. My experience covers a wide range of technologies and I have delivered a variety of web and mobile based solutions.

Comments and Discussions