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;
}
}
Related
I have something weird happening, maybe i don't know of something?
I am trying to populate a Drop Down List (in the editItemTemplate) and also, when the Grid View Loads populate a column, with strings instead of the id's that it contains now.
ASPX(the fiels that I have problem with are &
<asp:GridView ID="gvAdminArticleAdd".....
<asp:TemplateField HeaderText="invsId" SortExpression="invsId">
<EditItemTemplate>
<asp:DropDownList ID="ddl_invNames" runat="server" AutoPostBack="True" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lbl_insLabel" runat="server" Text='<%# Bind("invsId") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="ddl_invNamesNew" runat="server" AutoPostBack="True" />
</FooterTemplate>
</asp:TemplateField>
CodeBehind
protected void gvAdminArticleAdd_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//111111
//finding cotrols into the edit rows event
if (e.Row.RowState == DataControlRowState.Edit)
{
DropDownList ddlImages = (DropDownList)e.Row.FindControl("ddlImages");
ddlImages.DataSource = GetPdfs();
ddlImages.DataBind();
DropDownList ddlinvsNames = (DropDownList)e.Row.FindControl("ddl_invNames");
ArrayList invList = GetInvestigatorNames();
ddlinvsNames.DataSource = invList;
ddlinvsNames.DataBind();
}
//222222
//finding cotrols into rows
Label insLabel = (Label)e.Row.FindControl("lbl_insLabel");
int invsLabelId = int.Parse(insLabel.Text);
insLabel.Text = connection.GetInvsNameById(invsLabelId);
}
}
The problem that I have occur in the RowDataBound event, I can't figure it up what is wrong
//111111 and //22222 are working correctly(if I comment one of them), but not together. how can it be?
if I place them together I am getting an error on this line of code
int invsLabelId = int.Parse(insLabel.Text);
Object reference not set to an instance of an object.
so the error is in the previous line, but I can't figure why.
//111111 and //22222 are working correctly(if I comment one of them),
but not together. how can it be?
You do not need those two to work together. Only one will be available at a given time.
if (e.Row.RowState == DataControlRowState.Edit)
{
// EditItemTemplate - only controls inside EditItemTemplate are available here.
var ddlImages = (DropDownList)e.Row.FindControl("ddlImages");
var ddlinvsNames = (DropDownList)e.Row.FindControl("ddl_invNames");
}
else
{
// ItemTemplate - only controls inside ItemTemplate are available here.
var insLabel = (Label)e.Row.FindControl("lbl_insLabel");
}
The problem is that your dropDownList is added only during the EditMode. This you are retrieving in the if (e.Row.RowType == DataControlRowType.DataRow) code block. That is fine, you will be able to retrieve the dropdown list correctly. But in the same code block you are retrieving the Label ddl_invNames which will not be available in the edit mode, because you have added this label in the ItemTemplate. So the error must be in this place. However if you comment whole of this block, then the code goes directly to /222222, where you are trying to access the label, which will not be there at all during the edit mode of the row
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);
}
Here is my GV.
<asp:GridView ID="Grid1" runat="server" AutoGenerateColumns="false"
AllowPaging="True" OnPageIndexChanging="Grid1_PageIndexChanging">
<Columns>
<asp:BoundField DataField="One" HeaderText="One" />
<asp:BoundField DataField="Two" HeaderText="Two" />
<asp:BoundField DataField="Three" HeaderText="Three" />
</Columns>
</asp:GridView>
I'm populating the GV with a Stored Procedure.
table = PublicClass.Sql_GetTable("usp_GetReportGridView", "NCIU");
Grid1.DataSource = table;
Grid1.DataBind();
How can I sort using the column headers?
First you need to enable AllowSorting property to be true. When enabled, the grid renders LinkButton controls in the header for each column. When the button is clicked, the grid's SortCommand event is thrown. It's up to the you to handle this event in the code. Because DataGrid always displays the data in the same order it occurs in the data source, the typical logic sorts the data source, and then rebinds the data to the grid.look at code below:
//AllowSorting="True"
//OnSorting="GridView2_Sorting"
//SortExpression="name"
protected void GridView2_Sorting(object sender, GridViewSortEventArgs e)
{
//to check whether to display in ascending order or descending order
if (e.SortExpression.Trim() == this.SortField)
this.SortDirection = (this.SortDirection == "D" ? "A" : "D");
else
this.SortDirection = "A";
this.SortField = e.SortExpression;
TempTable();
}
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?');";
}
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;
}