I've racked my brains on trying to access the ID column of a gridview where a user selects a checkbox:
<asp:GridView ID="gvUserFiles" runat="server">
<Columns>
<asp:TemplateField HeaderText="Select" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The gridview columns are chkSelect (checkbox), Id, fileName, CreateDate
When a user checks a checkbox, and presses a button, i want to receive the "id" column value.
Here is my code for the button:
foreach (GridViewRow row in gvUserFiles.Rows)
{
var test1 = row.Cells[0].FindControl("chkSelect");
CheckBox cb = (CheckBox)(row.Cells[0].FindControl("chkSelect"));
//chk = (CheckBox)(rowItem.Cells[0].FindControl("chk1"));
if (cb != null && cb.Checked)
{
bool test = true;
}
}
The cb.checked always is returned false.
The Checkboxes being always unchecked can be a problem of DataBinding. Be sure you are not DataBinding the GridView before the button click event is called. Sometimes people stick the DataBinding on the Page_load event and then it keeps DataBinding on every PostBack. As it is called before the button click, it can make direct influence.
When the GridView is DataBound you lose all the state that came from the page.
If you Databind the GridView on the Page_load, wrap it verifying !IsPostBack:
if (!IsPostBack)
{
gvUserFiles.DataSource = data;
gvUserFiles.DataBind();
}
If that is not your case, you can try verifying the checked property based on the Request.Form values:
protected void button_OnClick(object sender, EventArgs e)
{
foreach (GridViewRow row in gvUserFiles.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("chkSelect");
if (cb != null)
{
bool ckbChecked = Request.Form[cb.UniqueID] == "on";
if (ckbChecked)
{
//do stuff
}
}
}
}
The Checked value of a CheckBox is sent by the browser as the value "on". And if it is not checked in the browser, nothing goes on the request.
You can achieve it using datakey like this
Add Datakey to your gridview
<asp:GridView ID="gvUserFiles" runat="server" DataKeyNames="Id">
and get it server side like this
string value = Convert.ToString(this.gvUserFiles.DataKeys[rowIndex]["Id"]);
Related
I have gridviewthat binded to database. There is checkbox in it that I want change display attribute of another div with checkbox checked value.
This is my back-end code in asp.net, but it isn't work! What can I do to solve it?
protected void gv_sourceGalleryPic_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "checkPic")
{
CheckBox chkItem = (CheckBox)gv_sourceGalleryPic.FindControl("ck_checkGalleryPic_copyMove");
if (chkItem.Checked == true)
{
div1.Style.Add(HtmlTextWriterStyle.Display, "block");
}
}
}
As i know, Asp.Net CheckBoxes do not have attributes named CommandName and CommandArgument. Therefore you can not use RowCommand event which is going to be fired when you change checked.
You should use some simple javascript codes instead of it like example code below:
function hidediv(chk) {
var element = document.getElementById("div1");
if (chk.checked)
{ element.style.display = 'none'; }
}
And then fire this function on change event of all checkboxes like this:
onchange="hidediv(this);"
By the way, if you want to change display a div section only, it would be better to use html input tag instead of asp.net checkbox.
You can use OnCheckedChanged event for checkbox instead onRowCommand like this:
Markup
<asp:GridView runat="server" ID="gv_sourceGalleryPic">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="ck_checkGalleryPic_copyMove" runat="server"
OnCheckedChanged="chkBox_CheckedChanged" AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind
protected void chkBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = sender as CheckBox;
if (chk.Checked)
{
div1.Style.Add(HtmlTextWriterStyle.Display, "block");
}
}
Try to find Div
HtmlGenericControl div1= (HtmlGenericControl )gv_sourceGalleryPic.FindControl("div1");
I have a Gridview with an ImageButton that should become visible for the selected row only. I'm doing this in the OnRowDataBound event, but it doesn't work.
protected void OnRowDataBoundMS(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
// some working code that handles the edit mode
}
else if (Gridview1.SelectedValue != null)
{
ImageButton ImgBut1 = e.Row.FindControl("ButtonUp") as ImageButton;
ImgBut1.Visible = true;
}
}
}
My gridview looks like this:
<asp:GridView runat="server"
ID="Gridview1"
DataSourceID="Milestones"
DataKeyNames="ID"
AutoGenerateColumns="false"
OnRowEditing="OnRowEditing"
OnRowDataBound="OnRowDataBoundMS"
OnSelectedIndexChanged="OnSelectedIndexChangedMS">
...
<asp:templatefield HeaderText="Order" ItemStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:ImageButton ID="ButtonUp" runat="server" OnClick ="OrderUp" ImageUrl="img/up.png" Visible="false"/>
</ItemTemplate>
</asp:templatefield>
I spent the last 3 hours on this and I start to freak out. Any hints on this? Martin
The other alternative is to use the SelectedIndexChanged event if you are using the Select command option:
protected void OnSelectedIndexChangedMS(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
Control ctl = row.FindControl("ButtonUp");
ctl.Visible = (row.RowState & DataControlRowState.Selected) != 0;
}
}
Something like that; RowDataBound may fire before the selected index gets updated (not sure about that...).
You can detect the selected row in the RowDataBound event handler with the RowState property, the same way you detect the edit row:
if ((e.Row.RowState & DataControlRowState.Selected) != 0)
{
...
}
An alternative is to set the Visible property of the ImageButton in the markup, with a data-binding expression:
<asp:ImageButton runat="server" Visible='<%# ((Container as GridViewRow).RowState & DataControlRowState.Selected) != 0 %>' ... />
Note: make sure that you call GridView1.DataBind() in the SelectedIndexChanged event handler, in order to refresh the content of the GridView.
I guess the key comment is what Brian Mains said about the RowDataBound firing before the selected Index gets updated. I can't prove this to be generally right, but it seems so. Therefore all attempts, even following ConnersFan suggestions didn't worked out. I did what Brian suggested and used the SelectedIndexChanged event handler, but without looping through all rows. The solution is actually quite simple:
protected void OnSelectedIndexChangedMS(object sender, EventArgs e)
{
Gridview1.DataBind();
ImageButton ImgBut1 = Gridview1.SelectedRow.FindControl("ButtonUp") as ImageButton;
ImgBut1.Visible = true;
}
I have GridView filled automatically as
<asp:GridView ID="gvValues" runat="server"
OnRowDataBound="gvValues_RowDataBound"
OnPageIndexChanging="gvValues_PageIndexChanging"
<Columns>
<asp:TemplateField HeaderText="#">
<ItemTemplate>
<%# gvValues.PageSize*gvValues.PageIndex+ Container.DisplayIndex+1 %>
<asp:CheckBox ID="chkProduct" runat="server" CssClass="chkProduct"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="online" meta:resourcekey="Online">
<ItemTemplate >
<asp:CheckBox ID="chkProductonline" runat="server" OnCheckedChanged ="chkProductonline_CheckedChanged" AutoPostBack="true"/>
</ItemTemplate>
</asp:TemplateField>
What I need is when I click on the chkProductonline checkbox, to fire an event and get the chkProductonline and chkProducton values. I have tried this but it always gives me null.
protected void chkProductonline_CheckedChanged(object sender, EventArgs e)
{
var chkProductonline = FindControl("chkProductonline") as CheckBox;
// bool ischeck = chkProductonline.Checked;
var chkProduct = gvValues.FindControl("chkProduct") as CheckBox;
}
I can't loop the GridView. I need to do this one-by-one. Is there another way to do that?
You can try this:
protected void chkProductonline_CheckedChanged(object sender, EventArgs e)
{
CheckBox chkProductonline = sender as CheckBox;
...
CheckBox chkProduct = chkProductionLine.NamingContainer.FindControl("chkProduct") as CheckBox;
...
}
You need to call FindControl on a specific row. You will not be able to call it on the entire GridView because there exists repeating content (i.e. multiple chkProductionlines and chkProducts). A row knows of its checkboxes, and not of the others.
So what you can do is first get the CheckBox that called the event (your sender parameter, chkProductionline) and use its NamingContainer. Since it is contained in a GridView row, cast the row as such as use it to find the other controls you may need.
protected void chkProductonline_CheckedChanged(object sender, EventArgs e)
{
CheckBox chkProductionline = (CheckBox)sender;
GridViewRow row = (GridViewRow)chkProductionline.NamingContainer;
CheckBox chkProduct = (CheckBox)row.FindControl("chkProduct");
}
I have two check boxes with the GridView TemplateField. I want to uncheck the checked boxes after submission. My gridview
<asp:GridView ID="GridView1" runat="server" HorizontalAlign="Center" DataKeyNames="ShiftID"
Width="177px" onrowdatabound="GridView1_RowDataBound1">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="ChbGrid" runat="server"
oncheckedchanged="ChbGrid_CheckedChanged" />
</ItemTemplate>
<HeaderTemplate>
<asp:CheckBox ID="ChbGridHead" runat="server" AutoPostBack="True"
Font-Bold="True" oncheckedchanged="ChbGridHead_CheckedChanged" />
</HeaderTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I tried in below mentioned methode
public void checkboxclear()
{
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox chkrow = (CheckBox)row.FindControl("ChbGrid");
if(chkrow.Checked==true)
{
chkrow.Checked = false;//it works
}
else
{
CheckBox chkrow1 = (CheckBox)row.FindControl("ChbGridHead");
if (chkrow1.Checked == true)
{
chkrow1.Checked = false;//it shows error like "Object reference not set to instance of an object"
}
}
}
How can I improve my code to solve this issue? Why I am unable to call these check boxes inside the aspx.cs page
You need to check for the RowType becuase your second checkbox is in the HeaderTemplate. For that gridview generates special HeaderRow. That you can directly access and set the value to it.
public void checkboxclear()
{
foreach (GridViewRow row in GridView1.Rows)
{
if(row.RowType == DataControlRowType.DataRow)
{
CheckBox chkrow = (CheckBox)row.FindControl("ChbGrid");
if(chkrow.Checked)
chkrow.Checked = false;
}
}
CheckBox chkrow1 = (CheckBox)GridView1.HeaderRow.FindControl("ChbGridHead");
if (chkrow1.Checked)
chkrow1.Checked = false;
}
Also you don't need to use the chkrow.Checked==true. chkrow.Checked it returns boolean value so that direactly should check in if condition.
I guess I don't know when you are calling this function, but the correct place to pre-set values is in the row databound event.
Having said that the reason your code is blowing up is that you are looking for the header check box in every row, and it is only in the header row. Just access the header through the gridviews header property and do your find control there.
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.headerrow(v=vs.110).aspx
Something like
CheckBox chkHeader = (CheckBox)Gridview1.HeaderRow.FindControl("ChbGridHead");
I have a grid with a few items which have a checkbox at the start of each row. I also have a select all checkbox at the top of the grid. The scenario is something like our gmail or yahoo inbox. My question is, suppose i disable a checkbox and then click on select all checkbox, the disabled checkbox should not be checked. Is there any solution for this? I have attached relevant pieces of code as follows.
*aspx file
<telerik:GridTemplateColumn UniqueName="CheckBoxTemplateColumn">
<HeaderTemplate>
<asp:CheckBox id="headerChkbox" OnCheckedChanged="ToggleSelectedState" AutoPostBack="True" runat="server"></asp:CheckBox>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox id="CheckBox1" OnCheckedChanged="ToggleRowSelection" AutoPostBack="True" runat="server"></asp:CheckBox>
</ItemTemplate>
</telerik:GridTemplateColumn>
*code behind
protected void ToggleRowSelection(object sender, EventArgs e) //selecting a particular row
{
((sender as CheckBox).NamingContainer as GridItem).Selected = (sender as CheckBox).Checked;
}
protected void ToggleSelectedState(object sender, EventArgs e) //select all rows
{
CheckBox headerCheckBox = (sender as CheckBox);
foreach (GridDataItem dataItem in grdCurrent.MasterTableView.Items)
{
(dataItem.FindControl("CheckBox1") as CheckBox).Checked = headerCheckBox.Checked;
dataItem.Selected = headerCheckBox.Checked;
}
}
You need to check if it is Enabled before setting it to Checked.
CheckBox headerCheckBox = (sender as CheckBox);
foreach (GridDataItem dataItem in grdCurrent.MasterTableView.Items)
{
if((dataItem.FindControl("CheckBox1") as CheckBox).Enabled) // add this condtion
{
(dataItem.FindControl("CheckBox1") as CheckBox).Checked = headerCheckBox.Checked;
dataItem.Selected = headerCheckBox.Checked;
}
}
Instead of using code behind to select all. I will use javascript or Jquery to do it. My method will be applying different css class for enabled and disabled checkbox like "enabled" and "disabled". In Jquery, I check the class and only tick the enabled checkboxes.