puoi farlo anche con un SqlDataSource

codice:
<asp:SqlDataSource 
 ConnectionString="<%$ ConnectionStrings:NomeApplicativo%>" 
 runat="server" 
 ID="sorgentedati" 
 SelectCommand="SELECT ID,campo1,campo2 FROM TABELLA"
 UpdateCommand="UPDATE TABELLA SET [campo1]=@campo1, [campo2]=@campo2 
 WHERE [ID]=@ID">
</asp:SqlDataSource>

(i campi con "@" devono essere BoundField o DataKeyNames nelle colonne della grid)

------------------------------------------------------------------
<asp:GridView 
  DataSourceID="sorgentedati" EditRowStyle-BackColor="#FFFFF0"
  AllowSorting="false" 
  Width="100%" 
  AutoGenerateColumns="false" 
  ID="gv" 
  DataKeyNames="ID" 
  runat="server">

<Columns>

<asp:BoundField DataField="campo1" HeaderText="Campo1" />
<asp:BoundField DataField="campo2" HeaderText="Campo2" />

<asp:CommandField ButtonType="Image" HeaderText="Opzioni" 
  ShowEditButton="True"  
  EditImageUrl="~/IMG/edit.png" 
  CancelImageUrl="~/IMG/cancel.png" 
  UpdateImageUrl="~/IMG/ok.png"  >
<ItemStyle HorizontalAlign="Center" />
</asp:CommandField>

</Columns>
</asp:GridView>


.....Oppure come già detto, dall'evento:
codice:
    Protected Sub gv_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gv.RowUpdating
        Dim riga As GridViewRow = gv.Rows(e.RowIndex)

        Dim nuovo_campo1 As String = DirectCast(riga.Cells(0).Controls(0), System.Web.UI.WebControls.TextBox).Text
        Dim nuovo_campo2 As String = DirectCast(riga.Cells(1).Controls(0), System.Web.UI.WebControls.TextBox).Text

        '...prendi cosi' i nuovi valori digitati dall'utente e li salvi nel db con una Update
    End Sub
Ma è un argomento piu' grande di questi semplici esempi, ti consiglio di studiartelo un po' piu' approfonditamente da qualche esempio in rete o manuale.