As I said earlier, you handle GridView's RowCommand event, just set CommandName for the ButtonField, and it will bubble GridView to raise it's RowCommand event. In RowCommand event, you can get the index of the row via CommandArgument supplied by the event argument. Here's a sample:
You have GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" >
<Columns>
<asp:ButtonField Text="Try me" CommandName="myRowSelect" />
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblSample" runat="server" Text='<%#String.Format("Label on row {0}",Ctype(Container,GridViewRow).RowIndex + 1)%>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And relevant code
Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
If e.CommandName = "myRowSelect" Then
Dim rowindex As Integer = CInt(e.CommandArgument)
Dim row As GridViewRow = GridView1.Rows(rowindex)
Dim lbl As Label = DirectCast(row.FindControl("lblSample"), Label)
Response.Write("You clicked row having Label with text: " & lbl.Text)
End If
End Sub
Of course, if you put CommandName to be Select, that would raise GridView's SelectedIndexChanging/:Selected events automatically,, where you could also do determining of the row, and again look controls on the row