GridView Checkbox Columns vs. Events - asp.net

I have created a gridview with a column of checkboxes. I want the user to select the checkboxes, click the register button (outside the gridview), and have a title from the selected row displayed. From what I've read I should put the checkbox check in the button click event. I have done so, but apparently the only time it enters that event is at page load and right before the page loads, all the selected checkboxes are wiped. Therefore, my check for a selected checkbox never comes out true. Is there an event that would a better time to run this check, or perhaps a way to hold these values through the page load? The following isn't all my code, just the affected portions.
protected void regButton_Click(Object sender, EventArgs e)
{
StringBuilder regClasses = new StringBuilder();
for (int i = 0; i < SQLQueryClassListings.Rows.Count; i++)
{
//Response.Write(SQLQueryClassListings.Rows[i].Cells[0].Text + " checkbox check ");
GridViewRow checkRow = SQLQueryClassListings.Rows[i];
bool reg = ((CheckBox)(checkRow.FindControl("RowCheckBox"))).Checked;
if (reg)
{
regClasses.Append(SQLQueryClassListings.Rows[i].Cells[0].Text + " ");
}
}
Response.Write(regClasses);
}
<asp:GridView ID="SQLQueryClassListings" AutoGenerateColumns="false" runat="server"
BorderWidth="1px" BackColor="White" CellPadding="5" BorderColor="Black" RowStyle-BorderColor = "Black"
HeaderStyle-BackColor="#0D69F2" HeaderStyle-ForeColor="White" AlternatingRowStyle-BackColor="#E8E8E8" HeaderStyle-BorderColor="Black" GridLines="Both">
<Columns>
<asp:BoundField HeaderText="Classes" DataField="LeafName" HeaderStyle-HorizontalAlign="Left" ItemStyle-Width="250"
ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
<asp:BoundField HeaderText="Teacher" DataField="TeacherName" HeaderStyle-HorizontalAlign="Left" ItemStyle-Width="200"
ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
<asp:BoundField HeaderText="Available" DataField="SemesterEnds" HeaderStyle-HorizontalAlign="Center"
ItemStyle-HorizontalAlign ="Center" ItemStyle-Width="150" ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
<asp:HyperLinkField HeaderText="Course Description & Career Tracks" DataNavigateUrlFields="ApplicableTracks"
Text="See Description" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign ="Center" ItemStyle-BorderColor="#ADADAD" HeaderStyle-BorderColor ="Black"/>
<asp:TemplateField HeaderText="Register" HeaderStyle-BorderColor="Black" ItemStyle-BorderColor = "#ADADAD" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox runat="server" ID="RowCheckBox"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<p>
<asp:Button ID="Button1" runat="server" Text="Register" OnClientClick="return confirm('You have sucessfully registered!')"
OnClick="regButton_Click" />

You need to get on the ItemDataBound event of the GridView control, find the CheckBox by ID, and do whatever you need.

It's hard to know for sure without seeing more of your code, but it sounds like your page is re-binding the GridView on postbacks (such as your regButton_Click event). So it rebuilds the GridView every time the page loads - even after your user clicks the register button.
If that is the case, you can fix this by changing the code you use to bind your GridView like this:
if (!this.IsPostback) {
SQLQueryClassListings.DataBind();
}
(This presumes that you have ViewState enabled for the page (or at least the GridView). There are other mechanisms you can use to communicate the client's state (such as checkbox selections) to the server, but ViewState (for all its faults) is the default tool for doign so in ASP.NET.)
A consequence is that the data shown in the GridView won't be completely up-to-date, but if you can tolerate that, this is a simple way to accomplish what you want.

You must read the checkboxes from the GridView.
So this code will bring back the IDs of the rows checked. It will give you the idea and then you can change it for what you need.
protected string getCheckedIds(GridView gv)
{
StringBuilder sb = new StringBuilder();
foreach (GridViewRow gvr in gv.Rows)
{
if (!gvrIsChecked(gvr)) // see below for this method
continue;
if (sb.Length > 0)
sb.Append(",");
sb.Append(gv.DataKeys[gvr.DataItemIndex].Value);
}
return sb.ToString();
}
protected bool gvrIsChecked(GridViewRow gvr)
{
// The location of your checkbox may be different.
object cb = gvr.Cells[0].Controls[gvr.Cells[0].Controls.Count - 2];
if (cb.GetType() != typeof(CheckBox))
return false;
if (!((CheckBox)cb).Checked)
return false;
return true;
}

Related

asp.net check if checkbox in gridview is checked

Gridview with a select-button, a boundfield and a checkbox. Binding the data to the gridview works fine. (the data in the DB has an NVARCHAR column for the bounfield and a BIT column for the checkbox.
When selecting a row via the 'Select' button, an event in code-behind is fired, and data from the 2 cells from the gridview are copied to 2 controls on the page: a textbox and checkbox.
The first works ok and I have no clue as to how to check if the checkbox in the gridview is checked or not. I need to know that so that I can populate other checkbox control accordingly.
(before I paste my code: I just spent some 12 hours searching for a solution here in SO and elsewhere. None of the numerous entries helped. So please bear with me...)
<asp:GridView ID="grv_Test1" runat="server" CssClass="myGrid"
AutoGenerateColumns="False" DataKeyNames="Test1_First_Name"
OnRowCommand="grv_Test1_RowCommand">
<Columns>
<asp:CommandField SelectText="sel'" ShowSelectButton="True" ControlStyle-CssClass="btn btn-primary myBtn-xs">
</asp:CommandField>
<asp:BoundField DataField="Test1_First_Name" HeaderText="Name"><HeaderStyle Width="85px" />
</asp:BoundField>
<asp:CheckBoxField DataField="Test1_Active" HeaderText="Active">
</asp:CheckBoxField>
</Columns>
<HeaderStyle CssClass="myGridHeader" />
</asp:GridView>
Code behind:
int my_Data_From_Grid = Convert.ToInt32(e.CommandArgument);
txb_Test1_Name.Text = grv_Test1.Rows[my_Data_From_Grid].Cells[1].Text; // this works
cbx_Test1_Active.Text = grv_Test1.Rows[my_Data_From_Grid].Cells[2].Text; // NOT working
if (Convert.ToString(grv_Test1.Rows[my_Data_From_Grid].Cells[2].Text) == "1") // NOT working either
{ cbx_Test1_Active.Checked = true; }
else
{ cbx_Test1_Active.Checked = false; }
if (Convert.ToString(grv_Test1.Rows[my_Data_From_Grid].Cells[2].Text) == "True") // NOT working either
{ cbx_Test1_Active.Checked = true; }
else
{ cbx_Test1_Active.Checked = false; }
Here is what I got when selecting Michael's row:
In the gridview Michael is "Active", and I need the checkbox at the top to be 'checked'.
How can it be done...? Thnaks a lot.
With CheckBoxFields and CheckBoxes, you need to get the Checked value to know whether or not it was actually checked. The Text value is actually another property of the CheckBox (see MSDN). You sometimes see this text to the left or right of the CheckBox itself.
So what you need to do is first get the CheckBox. Then use the Checked property of that CheckBox.
CheckBox checkBox = (CheckBox)grv_Test1.Rows[my_Data_From_Grid].Cells[2].Controls[0];
cbx_Test1_Active.Checked = checkBox.Checked;
protected void gvData_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox chkSelect = ((CheckBox)e.Row.FindControl("WasAudited"));
if (chkSelect.Checked)
chkSelect.Enabled = false;
}
}

Extract a BoundField to a Label

I have a DetailsView which works fine using a data access layer and a query string. However, I'd like to extract one of the fields and use it as the text in a label to go above the DetailsView as a title to that page.
Is this possible? And if so, how?
This is an abstract of the DetailsView:
<Fields>
<asp:BoundField DataField="bandname" HeaderText="Band" />
<asp:BoundField DataField="contactname" HeaderText="Contact" />
<asp:BoundField DataField="county" HeaderText="County" />
</Fields>
and the code behind:
if (Request.QueryString.Count != 0)
{
int id = int.Parse(Request.QueryString["bandid"]);
dtvBand.Visible = true;
List<Band> bandDetails = new List<Band> { BandDAL.AnonGetAllBandDetails(id) };
dtvBand.DataSource = bandDetails;
dtvBand.DataBind();
}
What I'd like to do is take the data in the first BoundField row and make it the text of a label. Pseudocode:
Label1.Text = (<asp:BoundField DataField="band")
I would not try to find the text on the DetailsView but in it's DataSource. You could use the DataBound event which is triggered after the DetailsView was databound, so it's ensured that the DataItem exists.
It depends on the Datasource of your DetailsView. Often it is a DataRowView. You have to cast it, then you can access it's column:
protected void DetailsView1_DataBound(Object sender, EventArgs e)
{
DetailsView dv = (DetailsView)sender;
string yourText = (string)((DataRowView)dv.DataItem)["ColumnName"];
Label1.Text = yourText;
}
If it's not a DataRowView use the debugger to see what dv.DataItem actually is.
I managed to achieve what I wanted using:
string titletext = dtvBand.Rows[0].Cells[1].Text.ToString();
dtvBand.Rows[0].Visible = false;
lblBand.Text = titletext;
It takes the first row of the DetailsView, puts it above the rest in a Label so it can be formatted as a header, then hides the first row of the DetailsView.
How about using a TemplateField as what Tim mentioned:
<Fields>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("Band") %>' />
</ItemTemplate>
</asp:TemplateField>
</Fields>

Gridview OnRowEditing event handler not firing

I have a gridview that uses list as it's datasource, this list is populated using entity framework and passed to my method where this data is binded to my grid view control. I seem to be having a problem with editing a row.
On designer I have added properties for the grid view to have a OnRowEditing handler and I have added a button for edit but my OnRowEditing event handler isn't firing. The breakpoint doesn't hit.
My Gridview control
<asp:GridView runat="server"
ID="grdNotes"
OnRowCommand="grdNotes_RowCommand"
AllowPaging="true"
AllowSorting="true"
EnableTheming="true"
AutoGenerateColumns="false"
OnPageIndexChanging="grdNotes_PageIndexChanging"
OnSorting="grdNotes_Sorting"
AlternatingRowStyle-BorderColor="Yellow"
PageSize="3"
AlternatingRowStyle-BackColor="Yellow"
OnRowEditing="grdNotes_RowEditing"
OnRowDeleting="grdNotes_RowDeleting"
DataKeyNames="NotesID" >
<Columns>
<asp:BoundField HeaderText="Title" DataField="NotesTitle" SortExpression="NotesTitle">
<ItemStyle Height="20px" Width="150px" />
</asp:BoundField>
<asp:BoundField HeaderText="Text" DataField="NotesText" SortExpression="NotesText">
<ItemStyle Height="20px" Width="250px" />
</asp:BoundField>
<%-- <asp:ButtonField CommandName="EditRow" DataTextField="Edit" HeaderText="Edit" />
<asp:ButtonField CommandName="DeleteRow" DataTextField="Delete" HeaderText="Delete" />--%>
<asp:CommandField ShowEditButton="true" />
<asp:CommandField ShowDeleteButton="true" />
<asp:CommandField ShowCancelButton="true" />
</Columns>
</asp:GridView>
Code behind
I retrieve the data from entity framework on Page_Init. I also have global variables
private List<NotesModel> list = new List<NotesModel>();
NotesModel nm = new NotesModel();
protected void Page_Init(object sender, EventArgs e)
{
NoteSearch ns = new NoteSearch(Business.ContextHelper.CurrentContext);
string[] urlArray = Request.RawUrl.Split('/');
string t = urlArray[4];
string[] relatedID = t.Split('=');
if (!IsPostBack)
{
// urlArray[3] is profile type , relatedID[1] is ID
list = ns.GetBasicNoteResults(nm, urlArray[3], relatedID[1]);
}
else
{
urlArray = Request.UrlReferrer.AbsoluteUri.Split('/');
t = urlArray[6];
relatedID = t.Split('=');
list = ns.GetBasicNoteResults(nm, urlArray[5], relatedID[1]);
}
GenerateGrid(list);
btnNotes.Text = "Notes: " + list.Count.ToString();
}
My binding method
private void GenerateGrid(List<NotesModel> list)
{
grdNotes.DataSource = list;
grdNotes.DataBind();
int count = grdNotes.Rows.Count;
//// Hide headers we don't want to expose
//grdNotes.HeaderRow.Cells[0].Visible = false;
//grdNotes.HeaderRow.Cells[3].Visible = false;
//grdNotes.HeaderRow.Cells[4].Visible = false;
//grdNotes.HeaderRow.Cells[5].Visible = false;
//for (int i = 0; i < count; i++)
//{
// // Loop through rows and hide cells
// grdNotes.Rows[i].Cells[0].Visible = false;
// grdNotes.Rows[i].Cells[3].Visible = false;
// grdNotes.Rows[i].Cells[4].Visible = false;
// grdNotes.Rows[i].Cells[5].Visible = false;
//}
// Finally add edit/delete buttons for these click event handlers
}
One final thing I noticed is when I hover over the edit row linkbutton, there is no query string, same with my paging at the bottom of the grid and my headers. Clicking on any of the grid controls take the user to:
http://localhost:8192/website/Company
and not
http://localhost:8192/website/Company/Advertiser/?id=8879
Summary
My gridview event handlers don't fire. Have I missed something to make this work?
You need to move this code:
GenerateGrid(list);
Inside the if(!Page.IsPostBack) block.
Each time your page posts back to the server (e.g. when you click the edit button), this code is rebuilding your GridView back to it's original state. This doesn't allow the RowEditing event to even occur, because you've essentially destroyed it and re-added it during Init (before it has a chance to occur).
Looking at your code some more, it appears you are using IsPostBack to determine the contents of the grid. You will need to modify that logic in order for this to work. Perhaps you can examine the contents of the query string being passed (or the number of / characters in the query string) to decide what parameters to pass to the GetBasicNoteResults method.
Your code will basically look like this:
if (!IsPostBack)
{
if (Some logic to decide what parameters to pass)
{
list = ns.GetBasicNoteResults(nm, urlArray[3], relatedID[1]);
}
else
{
list = ns.GetBasicNoteResults(nm, urlArray[5], relatedID[1]);
}
GenerateGrid(list);
}

GridView loses column contents during PostBack

I am having an issue with the behavior of a GridView between post backs.
The real problem comes from a TemplateField I define in the markup at column[0] with a child CheckBox control. Things work fine for the first, and second search executions. However, at some point between the second execution and anything that causes a post back there after, I lose the contents of the TemplateField.
Its only the the contents of the column and not the whole column itself that gets removed. The TemplateField is present in the source and shows a formated column at position 0 of the table.
CODE:
protected void ExecuteSearch(object sender, EventArgs e)
{
if (lb_SelectedFields.Items.Count == 0) { return; } //if no selected fields
//Generates custom SQL query based on user inputs and column Selections
BuildQuery(); // sets txbSqlText.Text = to the SQL string
DataTable Table = SqlAdapter.Select(new System.Data.SqlClient.SqlCommand(txbSqlText.Text));
for (int i = gv_SearchResults.Columns.Count - 1; i > 0; i--)
{ gv_SearchResults.Columns.RemoveAt(i); } //removes all the columns except[0]
foreach (ListItem Item in lb_SelectedFields.Items) //adds all the user defined columns
{
//Column object that is able to find the column definition
Column Col = ColumnsBasedOnFocus.FindColumName(Item.Value);
if (Col.Type == "HyperLink") { gv_SearchResults.Columns.Add(CreateHyperLinkField(Col)); }
else { gv_SearchResults.Columns.Add(CreateBoundColumn(Col, true)); } //true is if the column is visable
}
gv_SearchResults.DataSource = Table;
gv_SearchResults.DataBind();
}
ASP.NET:
<asp:GridView ID="gv_SearchResults" runat="server" GridLines="None" CellSpacing="0"
CellPadding="0" AutoGenerateColumns="false" CssClass="TABLE_LIGHTBLUE" Width="100%">
<HeaderStyle CssClass="TABLE_LIGHTBLUE_HEADERROW" />
<Columns>
<asp:TemplateField ItemStyle-Width="30" ItemStyle-Wrap="false">
<HeaderTemplate>
<center>
<asp:Button ID="btn_SelectAll" runat="server" OnClick="SelectAll" Text="All" CssClass="TEXT_SMALL" />
<asp:CheckBox ID="chk_Placeholder" runat="server" Visible="false" /></center>
</HeaderTemplate>
<ItemTemplate>
<center>
<asp:CheckBox ID="chk_Select" runat="server" Visible="true" />
<asp:Label ID="lbl_AssetGID" runat="server" Visible="false" Text='<%# Bind("i_GID") %>' /></center>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Found a link that describes a similar situation.
https://connect.microsoft.com/VisualStudio/feedback/details/104994/templatefield-in-a-gridview-doesnt-have-its-viewstate-restored-when-boundfields-are-inserted#details
They describe a bug in ASP.Net code that fails to properly manage view states with template fields in dynamically generated grid views.
Basically TemplateFields can't be properly restored from ViewState, and if you modify the ASPX-declared columns programmatically, it can't create them from the declarations either.
The only solution I could get working was to create a new class deriving from TemplateField that in the constructor set the ItemTemplate to an ITemplate-derived class, which means having to define the template programmatically instead of declaratively.
You can also rebind the gridview on each postback but that's its own can of worms.

How to add a "confirm delete" option in ASP.Net Gridview?

How to add a "confirm delete" option in ASP.Net Gridview ?
This should do it.
I found it here: http://forums.asp.net/p/1331581/2678206.aspx
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:ImageButton ID="DeleteButton" runat="server" ImageUrl="~/site/img/icons/cross.png"
CommandName="Delete" OnClientClick="return confirm('Are you sure you want to delete this event?');"
AlternateText="Delete" />
</ItemTemplate>
</asp:TemplateField>
If your Gridview used with AutoGenerateDeleteButton="true" , you may convert it to LinkButton:
Click GridView Tasks and then Edit Columns.
Select Delete in Selected fields, and click on Convert this field into a TemplateField. Then click OK:
Now your LinkButton will be generated. You can add OnClientClick event to the LinkButton like this:
OnClientClick="return confirm('Are you sure you want to delete?'); "
I did this a bit different. In my gridview I set the AutoGenerateDeleteButton="true". To find the delete button I use jQuery and add a click event to the found Anchors.
jQuery("a").filter(function () {
return this.innerHTML.indexOf("Delete") == 0;
}).click(function () { return confirm("Are you sure you want to delete this record?");
});
This is quick and simple for what I need to do. Just be mindful that Every Anchor in the page that displays Delete will be selected by jQuery and will have the event added to it.
I like this way of adding a confirmation prompt before deleting a record from a gridview. This is the CommandField definition nested within a GridView web control in the aspx page. There's nothing fancy here--just a straightforward Commandfield.
<asp:CommandField ShowEditButton="true" UpdateText="Save" ShowDeleteButton="True">
<ControlStyle CssClass="modMarketAdjust" />
</asp:CommandField>
Then, all I had to do was add some code to the RowDeleting event of the GridView control. This event fires before the row is actually deleted, which allows you to get the user's confirmation, and to cancel the event if he doesn't want to cancel after all. Here is the code that I put in the RowDeleting event handler:
Private Sub grdMarketAdjustment_RowDeleting(sender As Object, e As GridViewDeleteEventArgs) Handles grdMarketAdjustment.RowDeleting
Dim confirmed As Integer = MsgBox("Are you sure that you want to delete this market adjustment?", MsgBoxStyle.YesNo + MsgBoxStyle.MsgBoxSetForeground, "Confirm Delete")
If Not confirmed = MsgBoxResult.Yes Then
e.Cancel = True 'Cancel the delete.
End If
End Sub
And that seems to work fine.
I didn't want any image so i modified the answer given by #statmaster to make it simple entry along with the other columns.
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Delete" OnClientClick="return confirm('Are you sure you want to delete this entry?');">Delete </asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
The colour of the text can be changed using the Forecolor Property.
You can do using OnClientClick of button.
OnClientClick="return confirm('confirm delete')"
I quite like adding the code in the GridView RowDataBound event to inform the user exactly which item they are trying to delete. Slightly better user experience?
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkBtnDelete = e.Row.FindControl("lnkBtnDelete") as LinkButton;
// Use whatever control you want to show in the confirmation message
Label lblContactName = e.Row.FindControl("lblContactName") as Label;
lnkBtnDelete.Attributes.Add("onclick", string.Format("return confirm('Are you sure you want to delete the contact {0}?');", lblContactName.Text));
}
}
Try this:
I used for Update and Delete buttons. It doesn't touch Edit button. You can use auto generated buttons.
protected void gvOperators_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType != DataControlRowType.DataRow) return;
var updateButton = (LinkButton)e.Row.Cells[0].Controls[0];
if (updateButton.Text == "Update")
{
updateButton.OnClientClick = "return confirm('Do you really want to update?');";
}
var deleteButton = (LinkButton)e.Row.Cells[0].Controls[2];
if (deleteButton.Text == "Delete")
{
deleteButton.OnClientClick = "return confirm('Do you really want to delete?');";
}
}
This is my preferred method. Pretty straight forward:
http://www.codeproject.com/KB/webforms/GridViewConfirmDelete.aspx
Although many of these answers will work, this shows a straightforward example when using CommandField in GridView using the OnClientClick property.
ASPX:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="OnRowDataBound"... >
<Columns>
<!-- Data columns here -->
<asp:CommandField ButtonType="Button" ShowEditButton="true" ShowDeleteButton="true" ItemStyle-Width="150" />
</Columns>
</asp:GridView>
ASPX.CS:
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != GridView1.EditIndex)
{
(e.Row.Cells[2].Controls[2] as Button).OnClientClick = "return confirm('Do you want to delete this row?');";
}
}
I was having problems getting a commandField Delete button to honor the 'return false' response to when a user clicked cancel on the 'Are you sure' pop-up that one gets with using the javascript confirm() function. I didn't want to change it to a template field.
The problem, as I see it, was that these commandField Buttons already have some Javascript associated with them to perform the postback. No amount of simply appending the confirm() function was effective.
Here's how I solved it:
Using JQuery, I first found each delete button on the page (there are several), then manipulated the button's associated Javascript based on whether the visitor agreed or canceled the confirming pop-up.
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$('input[type="button"]').each(function() {
if ($(this).val() == "Delete") {
var curEvent = $(this).attr('onclick');
var newContent = "if(affirmDelete() == true){" + curEvent + "};"
$(this).attr('onclick',newContent);
}
});
}
function affirmDelete() {
return confirm('Are you sure?');
}
</script>
This code is working fine for me.
jQuery("a").filter(function () {
return this.innerHTML.indexOf("Delete") == 0;
}).click(function () { return confirm("Are you sure you want to delete this record?");
});
I love the JavaScript solution and have some updates to work with dynamic ajax loading:
$(document).on("click", "a", function () {
if (this.innerHTML.indexOf("Delete") == 0) {
return confirm("Are you sure you want to delete this record?");
}
});
Hope it help ;)
This is my method and it works perfectly.
asp
<asp:CommandField ButtonType="Link" ShowEditButton="true" ShowDeleteButton="true" ItemStyle-Width="5%" HeaderStyle-Width="5%" HeaderStyle-CssClass="color" HeaderText="Edit"
EditText="<span style='font-size: 20px; color: #27ae60;'><span class='glyphicons glyph-edit'></span></span>"
DeleteText="<span style='font-size: 20px; color: #c0392b;'><span class='glyphicons glyph-bin'></span></span>"
CancelText="<span style='font-size: 20px; color: #c0392b;'><span class='glyphicons glyph-remove-2'></span></span>"
UpdateText="<span style='font-size: 20px; color: #2980b9;'><span class='glyphicons glyph-floppy-saved'></span></span>" />
C# (replace 5 with the column number of the button)
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
}
else {
((LinkButton)e.Row.Cells[5].Controls[2]).OnClientClick = "return confirm('Do you really want to delete?');";
}

Resources