I have a grid view which have checkbox. Now how to get its value on serverside.
<ItemTemplate>
<asp:CheckBox
ID="chkEditable" runat="server" AlternateText="Is Editable"
OnCheckedChanged="chkEditable_CheckedChanged"
AutoPostBack="true" Value='<%# Eval("PK_ID")%>' />
</ItemTemplate>
protected void chkEditable_OnCheckedChanged(object sender, EventArgs e)
{
GridViewRow gv = (GridViewRow)(((Control)sender).NamingContainer);
int pk = this.GridView1.DataKeys[gv.RowIndex].Value.ToString();
// Get the reference of this CheckBox
CheckBox chk = gv.FindControl("chkEditable") as CheckBox ;
//do stuff
}
Add the event handler manually to the code behind page
Related
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");
}
While getting the value I'm getting Object reference not set to an instance of an object. how to get labeled label value in code behind. How to get the value in custom event
<asp:GridView runat="server" ID="gridviewQuoteDetails" EmptyDataText="No records Found..." AutoGenerateEditButton="false" OnRowEditing="gridviewQuoteDetails_RowEditing" OnRowUpdating="gridviewQuoteDetails_RowUpdating" DataKeyNames="id" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<a href='Quote.aspx?val=<%#Eval("id")%>'>
<asp:Label ID="lblid" runat="server" Text='<%#Eval ("id")%>'></asp:Label>
</a>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" Text="Edit" runat="server" CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="LinkButton2" Text="Update" runat="server" OnClick="OnUpdate" />
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
code behind
protected void OnUpdate(object sender, EventArgs e)
{
string qouteid = ((Label)gridviewQuoteDetails.FindControl("lblid")).Text;
GridViewRow row = (sender as LinkButton).NamingContainer as GridViewRow;
string id = (row.Cells[0].Controls[0] as TextBox).Text;
string Description = (row.Cells[1].Controls[0] as TextBox).Text;
}
Gridview is a collection of rows right, but you are trying to search the control directly within the gridview thus ((LinkButton)gridviewQuoteDetails.FindControl("lbllnknm")) will be null and when you are trying to access the Text property of LinkButton you are getting NRE error.
You need to loop through the rows of your gridview control to access each linkbutton present in each row like this:-
foreach (GridViewRow row in gridviewQuoteDetails.Rows)
{
LinkButton lbllnknm= row.FindControl("lbllnknm") as LinkButton;
}
But ideally you would not be needing this. I guess you are trying to get the value in OnRowEditing event handler. If that is the case then you can fetch the value of linkbutton like this:-
protected void gridviewQuoteDetails_RowEditing(object sender, GridViewUpdateEventArgs e)
{
string qouteid = ((Label)gridviewQuoteDetails.Rows[e.NewEditIndex]
.FindControl("lbllnknm")).Text;
}
Update 2:
As per your comment you are trying to access the LinkButton text on click of LinkButton itself which means the event is raised by LinkButton itself. You can simply use the sender object like this:-
protected void OnUpdate(object sender, EventArgs e)
{
LinkButton LinkButton2 = sender as LinkButton;
GridViewRow row = LinkButton2.NamingContainer as GridViewRow; //Get the gridview row
Label lblid = row.FindControl("lblid") as Label;
string qouteid = lblid.Text;
}
I have a LinkButton within my ItemTemplate of my ListView:
<asp:ListView ID="lvNotification" runat="server">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lbReject" OnClick="Reject_Click" CommandArgument='<%# Eval("offerID") %>' Text="Reject" />
</ItemTemplate>
</asp:ListView>
Then in my code I have:
protected void Reject_Click(object sender, EventArgs e)
{
var lbreject = lvNotification.Items[0].FindControl("lbReject") as LinkButton;
string c = lbreject.CommandArgument;
}
The ListView retrieves 4 rows correctly, and I have placed the Eval("offerID") and it shows an offerID for each item in the list, however when I place it as the CommandArgument in the LinkButton and debug it, it shows the value 1 on ever item in the ListView, I am trying to place the offerID in each LinkButton CommandArgument and be able to access it, but I cannnot do so.
What am I doing wrong?
That is because you are always checking the first item (0 index). You can get the LinkButton from the sender and check its command argument.
protected void Reject_Click(object sender, EventArgs e)
{
var lbreject = (LinkButton)sender;
string c = lbreject.CommandArgument;
}
Here actually OnItemCommand event of ListView can be handy. This way you can control all events from the single point:
<asp:ListView ID="lvNotification" OnItemCommand="lvNotification_OnItemCommand" runat="server">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lbReject" CommandName="Reject_Click" CommandArgument='<%# Eval("offerID") %>' Text="Reject" />
</ItemTemplate>
</asp:ListView>
protected void lvNotification_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Reject_Click"))//or any other event
{
LinkButton lbreject = (LinkButton) sender;
string c = lbreject.CommandArgument;
}
}
<asp:TemplateField HeaderText="Team Leader">
<ItemTemplate>
<asp:Label ID="gvuser_teamleader" runat="server" Text='<%# Bind("TeamLeaderID") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtuserteamleader" runat="server" Width="100px" Text='<%# Eval("TeamLeaderID") %>' CssClass="textboxstyle roundedcorner aligncenter gradientskyblue"></asp:TextBox>
<asp:ListBox ID="listboxuserteamleader" runat="server" Width="110px" AutoPostBack="true" OnSelectedIndexChanged="listboxuserteamleader_SelectedIndexChanged" CssClass="textboxstyle roundedcorner aligncenter gradientskyblue"></asp:ListBox>
<asp:DropDownExtender ID="DropDownExtender3" runat="server" TargetControlID="txtuserteamleader" DropDownControlID="listboxuserteamleader"></asp:DropDownExtender>
</EditItemTemplate>
</asp:TemplateField>
When I am trying to fire the selected listbox index changed event and trying to bind the listbox selected value to textbox am getting this error. Also both controls are inside the gridview edit item template field.
My code:
protected void listboxuserteamleader_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (GridViewRow gvr in gvusers.Rows)
{
TextBox txtuserteamleader = (TextBox)gvusers.FindControl("txtuserteamleader");
ListBox listboxuserteamleader = (ListBox)gvusers.FindControl("listboxuserteamleader");
txtuserteamleader.Text = listboxuserteamleader.SelectedValue.ToString();
}
}
just try the below code:
protected void listboxuserteamleader_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (GridViewRow gvr in gvusers.Rows)
{
TextBox txtuserteamleader = (TextBox)gvr.FindControl("txtuserteamleader");
ListBox listboxuserteamleader = (ListBox)gvr.FindControl("listboxuserteamleader");
if(txtuserteamleader !=null && listboxuserteamleader !=null)
{
txtuserteamleader.Text = listboxuserteamleader.SelectedValue.ToString();
}
}
}
Actually what was you problem : you have created instance of gridview "gvusers" as gvr for each row... so in foreach you must have to use that instance not the "gvusers" ... here you were making mistake...
That's all
try this:
protected void listboxuserteamleader_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (GridViewRow gvr in gvusers.Rows)
{
TextBox txtuserteamleader = (TextBox)gvr.FindControl("txtuserteamleader");
ListBox listboxuserteamleader = (ListBox)gvr.FindControl("listboxuserteamleader");
txtuserteamleader.Text = listboxuserteamleader.SelectedValue.ToString();
}
}
When you iterate through the rows of the GridView, you have to search for the control inside that row, so the error you made is that you were searching it in the entire GridView, where each row would have this control. So you need to search it in a row.
I have a GridView with a TemplateField column that I put PlaceHolder controls in. During the DataBound event for the GridView I dynamically add a few CheckBoxes to the PlaceHolder. That works fine and displays as expected.
My problem is that during the RowUpdating event the PlaceHolder contains no controls; my CheckBoxes are missing. I also noticed that they're missing during the RowEditing event.
I want to be able to get the values of the CheckBoxes during the RowUpdating event so I can save them to the database.
Here's some example code. I've trimmed out a lot to reduce size, but if you want to see specifics just ask and I'll be happy to add more.
HTML:
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False"
ondatabound="gridView_DataBound" onrowupdating="gridView_RowUpdating"
onrowediting="gridView_RowEditing" DataKeyNames="ID">
<Columns>
<asp:TemplateField HeaderText="Countries">
<ItemTemplate>
<asp:PlaceHolder ID="countriesPlaceHolder" runat="server"></asp:PlaceHolder>
</ItemTemplate>
<EditItemTemplate>
<asp:PlaceHolder ID="countriesPlaceHolder" runat="server"></asp:PlaceHolder>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="editButton" runat="server" CommandName="Edit" Text="Edit"></asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="updateButton" runat="server" CommandName="Update" Text="Update"></asp:LinkButton>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind:
// This method works fine, no obvious problems here.
protected void gridView_DataBound(object sender, EventArgs e)
{
// Loop through the Holidays that are bound to the GridView
var holidays = (IEnumerable<Holiday>)gridView.DataSource;
for (int i = 0; i < holidays.Count(); i++)
{
// Get the row the Holiday is bound to
GridViewRow row = gridView.Rows[i];
// Get the PlaceHolder control
var placeHolder = (PlaceHolder)row.FindControl("countriesPlaceHolder");
// Create a CheckBox for each country and add it to the PlaceHolder
foreach (Country country in this.Countries)
{
bool isChecked = holidays.ElementAt(i).Countries.Any(item => item.ID == country.ID);
var countryCheckBox = new CheckBox
{
Checked = isChecked,
ID = country.Abbreviation + "CheckBox",
Text = country.Abbreviation
};
placeHolder.Controls.Add(countryCheckBox);
}
}
}
protected void gridView_RowEditing(object sender, GridViewEditEventArgs e)
{
// EXAMPLE: I'm expecting checkBoxControls to contain my CheckBoxes, but it's empty.
var checkBoxControls = gridView.Rows[e.NewEditIndex].FindControl("countriesPlaceHolder").Controls;
gridView.EditIndex = e.NewEditIndex;
BindData();
}
protected void gridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
// EXAMPLE: I'm expecting checkBoxControls to contain my CheckBoxes, but it's empty.
var checkBoxControls = ((PlaceHolder)gridView.Rows[e.RowIndex].FindControl("countriesPlaceHolder")).Controls;
// This is where I'd grab the values from the controls, create an entity, and save the entity to the database.
gridView.EditIndex = -1;
BindData();
}
This is the article that I followed for my data binding approach: http://www.aarongoldenthal.com/post/2009/04/19/Manually-Databinding-a-GridView.aspx
You need to call your BindData() method on page load.
"Dynamic controls or columns need to be recreated on every page load, because of the way that controls work. Dynamic controls do not get retained so you have to reload them on every page postback; however, viewstate will be retained for these controls."
See Cells in gridview lose controls on RowUpdating event
Also in the article you linked, there is an ItemTemplate and an EditItemTemplace because they have different displays, i.e. read only and editable. Yours are the same so I think you could simplify your design:
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" ondatabound="gridView_DataBound">
<Columns>
<asp:TemplateField HeaderText="Countries">
<ItemTemplate>
<asp:PlaceHolder ID="countriesPlaceHolder" runat="server"></asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="editButton" runat="server" Text="Edit" onclick="editButton_Click" ></asp:LinkButton>
<asp:LinkButton ID="updateButton" runat="server" Text="Update" onclick="updateButton_Click" ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind:
protected void gridView_DataBound(object sender, EventArgs e)
{
// Loop through the Holidays that are bound to the GridView
var holidays = (IEnumerable<Holiday>)gridView.DataSource;
for (int i = 0; i < holidays.Count(); i++)
{
// Get the row the Holiday is bound to
GridViewRow row = gridView.Rows[i];
// Get the PlaceHolder control
var placeHolder = (PlaceHolder) row.FindControl("countriesPlaceHolder");
var countryCheckBox = new CheckBox
{
Checked = true,
ID = "auCheckBox",
Text = "Aus",
Enabled = false
};
placeHolder.Controls.Add(countryCheckBox);
var editButton = (LinkButton)row.FindControl("editButton");
editButton.CommandArgument = i.ToString();
var updateButton = (LinkButton)row.FindControl("updateButton");
updateButton.CommandArgument = i.ToString();
updateButton.Visible = false;
}
}
protected void editButton_Click(object sender, EventArgs e)
{
LinkButton editButton = (LinkButton) sender;
int index = Convert.ToInt32(editButton.CommandArgument);
GridViewRow row = gridView.Rows[index];
// Get the PlaceHolder control
LinkButton updateButton = (LinkButton)row.FindControl("updateButton");
updateButton.Visible = true;
editButton.Visible = false;
CheckBox checkbox = (CheckBox)row.FindControl("auCheckBox");
if (checkbox != null)
{
checkbox.Enabled = true;
// Get value and update
}
}
protected void updateButton_Click(object sender, EventArgs e)
{
LinkButton updateButton = (LinkButton)sender;
int index = Convert.ToInt32(updateButton.CommandArgument);
GridViewRow row = gridView.Rows[index];
// Get the PlaceHolder control
LinkButton editButton = (LinkButton)row.FindControl("updateButton");
editButton.Visible = true;
updateButton.Visible = false;
CheckBox checkbox = (CheckBox)row.FindControl("auCheckBox");
if (checkbox != null)
{
// Get value and update
checkbox.Enabled = false;
}
}
If you want to be it enabled from the get go, just remove the enabled checks and you can delete your edit button.
Hope that helps.