CheckBox in ASP.NET GridView template field does not retain it's value on submit - asp.net

I'm trying to use CheckBoxes within a GridView's TemplateField to select multiple entries from that GridView. The GridView's data source is a list of items that is generated at page load.
<asp:GridView ID="GridView" runat="server" AutoGenerateColumns="False"
AllowPaging="True" onpageindexchanging="TANsGridView_PageIndexChanging"
DataKeyNames="GUID">
<Columns>
<asp:TemplateField ShowHeader="False" HeaderText="Checker">
<ItemTemplate>
<asp:CheckBox ID="SelectCheckbox" runat="server" />
</ItemTemplate>
</asp:TemplateField>
The problem is that when I press a submit button, all the CheckBoxes are returned with the Checked property as 'false'.
For cycling through the rows, I use:
foreach (GridViewRow row in TANsGridView.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("SelectCheckbox");
}
What should I use in order to have access to the correct value?
Thanks, Catalin

Are you mistakingly rebinding the gridview on page load every time? The gridview binding code should be wrapped in a if statement ensuring it's only done on not postback.
Am I supposed to put this here for an accept check now? :)

if your are binding the grid on page load.load the grid like this.
if(!ispostback)
{
..........loading data to databind.
}

Related

ASP.NET Gridview: How do I stop a <span></span> within a Gridview from resetting when posting back?

I have a Gridview which contains some controls which are updated from the server when the user makes a selection from a gridview.
After making their selection from a drop down list the user can enter a percentage into a textbox on a row and I have some javascript which then carries out some calculations and outputs to a span within an item template in the Gridview.
This all works but if the user then makes another drop down list selection on any row all the spans in the gridview are reset to blank (I've tried with various controls, both asp.net and html).
This is all inside an Update Panel.
Code:
<asp:GridView runat="server" ID="gdvIngredients" AutoGenerateColumns="false" CssClass="table table-stripped"
GridLines="None" Visible="false" ShowFooter="true" EnableViewState="true">
<Columns>
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:Label runat="server" ID="lblId" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Ingredient" ItemStyle-Width="12%">
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlName" AutoPostBack="true" OnSelectedIndexChanged="ddlName_SelectedIndexChanged"
ForeColor="Black" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="%" ItemStyle-Width="6%">
<ItemTemplate>
<asp:TextBox runat="server" Text="0" Width="50px" ID="txtPercentage" onkeyup="calculate(this);"
ForeColor="Black" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="kj" ItemStyle-Width="6%">
<ItemTemplate>
<asp:Label runat="server" ID="lblKj" CssClass="Kj" Style="display: none;" />
<span runat="server" id="spnKj" class="NewKj">0</span>
</ItemTemplate>
From your question what i have understood is that you are doing calculation in javascript and assigning it to span,but when next postback happens the value is not retained...If i am right i would suggest you to try the following steps.Use HiddenFields also to assign Values as HiddenFields Retain values during PostBacks.
Add Hidden field in Item Template
Set "calculate" function to Textbox from Codebehind(from rowdatabound event) & also pass the currosponding HiddenField Value to it as calculate(this,'HiddenFieldId');
protected void grd_RowDataBound(object sender,GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HiddenField hdn = ((HiddenField)e.Row.FindControl("HiddenFieldID"));
TextBox txtPercentage = (TextBox)e.Row.FindControl("txtPercentage");
HtmlGenericControl spnKj=(HtmlGenericControl )e.Row.FindControl("spnKj");
txtPercentage.Attributes["onClick"]="calculate(this,'"+hdn .ClientID+"');"
spnKj.innerHTML=hdn.Value;
}
}
Javascript:
Assign Calculated Value to Hidden Field...
function calculate(hdnID)
{
var CalcValue=//do your Calculation
document.getElementByID(hdnID).Value=CalcValue;
}
3.In the DropDown PostBack Event Bind the GridView Again.
The above code should take care of the Issue You are facing.
You can use the "AutoPostBack" property to control the Postback event of some controls.
Have a look if your dropdown list selection do any PostBack.
If it does, then span values disappear, becuase Span is not ASP.NET webcontrol. After pages is postback, asp.net webcontrol values are restored from ViewState. So, spans doesn't have ViewState and no values are restored.
You can try to change your tag to
<span runat="server" id="spanIDHere">SomeValue here</span>
runat="server" makes span to be HtmlGenericControl and maintains its ViewState.
Span values would not be saved after postback if you update them using Javascript. You should call server-side function to update span values or try to use Hidden fields to store your values.

getting the RadGrid checkbox column value in server

I have a RadGrid having a checkbox column, i have added the column as a ItemTemplate to make it editable in the regular mode.
<telerik:GridTemplateColumn UniqueName="IsSelected" DataField="IsSelected">
<ItemTemplate>
<asp:CheckBox ID="chkBoolean" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsSelected")) %>'Enabled='<%# Convert.ToBoolean(Eval("IsSelectionDisable")) %>' />
</ItemTemplate>
</telerik:GridTemplateColumn>
Using this I am able to display a checkbox as editable. Now my problem is how do i get the checked value of the checkox for saving it when the user has changed the checkbox. On click of a button i need to get all the rows that are still checked and save them. The below code does not work as it does not get the checkbox. Is there any way possible to get the value.
foreach (GridDataItem item in rgUnavailResult.MasterTableView.Items)
{
(CheckBox)item["IsSelected"].Controls[0]
}
Thanks
Found the checkbox
((System.Web.UI.WebControls.CheckBox)(item["IsSelected"].FindControl("chkBoolean")))

Gridview custom paging inside wizard control doesn't work correct in asp.net

I have a page where guests can be selected.
This page contains an update panel, within the update panel there is a wizard control and in the wizard control there is a gridview (Panel-> Update Panel -> wizard control -> gridview)
Now the paging doesn't work well, I searched the internet for answers but I didn't find the right answer. I use custom paging.
When I want to change the pagenumber (to the second or last page) it works fine. But when I want to select a row or go to another page, the gridview doesn't work correct. When I select A row on the second or last page (other page's don't work) the selected guest (item) is always one of the first page. When I want change to another page (from the second or last page) it doesn't work and stays on the selected page.
Is there a way to solve this problem?
part of the code:
<asp:Panel ID="PnlRe" Style="display: none; ... >
<asp:UpdatePanel ID="UpdtPnlDetail" runat="server" UpdateMode="Conditional">
<ContentTemplate>
...
<asp:Wizard ID="wzd" runat="server" ... >
...
<asp:WizardStep ID="WizardStep3" runat="server" Title="Naam">
...
<asp:Gridview ID="Gridview1" runat="server" AutoGenerateColumns="False"
DataKeyNames="GastID,Versie" DataSourceID="odsGasten" EmptyDataText="...."
OnRowCommand="Gridview1_RowCommand" OnPageIndexChanging="Gridview1_PageIndexChanging"
OnPageSizeChanging="Gridview1_PageSizeChanging" OnSearching="Gridview1_Searching"
OnSorting="Gridview1_Sorting" OnRowDataBound="Gridview1_RowDataBound"
CausesValidation="False" meta:resourcekey="..." PagerType="Custom"
ShowFilter="True" ShowInsertRecord="True" ShowPageSizer="True" UseSubmitBehaviour="False">
<Columns>
<asp:TemplateField ShowHeader="False" meta:resourcekey="...">
<ItemTemplate>
<asp:ImageButton runat="server" CommandName="Select" CausesValidation="False" SkinID="uprowbutton"
ToolTip="..." ID="ImgBtnSelect" meta:resourcekey="...">
</asp:ImageButton>
</ItemTemplate>
</asp:TemplateField>
... Boundfields ...
</Columns>
</asp:Gridview>
...
</asp:WizardStep>
...
</asp:Wizard>
</ContentTemplate>
</asp:UpdatePanel>
protected void Gridview1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.odsGasten.FilterExpression = searchText;
this.Gridview1.DataBind();
this.UpdtPnlDetail.Update();
}
there is a tricky way to achieve this, you have to manipulate your data source.
for example if you are using a datatable you have to select first ten elements of dt and bind it to grid, and when next button is clicked get next ten elements of dt and bind it to gridview. this will make your task easy and will get more performance for your page.
I can see that this.GridView1.DataBind() is called in GridView1_PageIndexChanging, but where is the currentPageIndex stored and updated with the page index you want to navigate to and when in the process is it happening?
Sounds to me like you have a viewstate problem.
You need to make sure that between Init and Load you have the grid's source set, either from viewstate or from a new bind-ing.

Change value of control inside a gridview templatefield itemtemplate

hi I have this gridview like this.
<asp:DropDownList ID="triggerDropDown" runat="server" AutoPostBack="true" onselectedindexchanged="triggerDropDown_SelectedIndexChanged">
<asp:GridView ID="myGridView" run="server">
<Columns>
<asp:TemplateField HeaderText="Column 1">
<ItemTemplate>
<asp:DropDownList ID="myDropDown1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Column 2">
<ItemTemplate>
<asp:DropDownList ID="myDropDown2" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
now, when I change my triggerDropDown I want to change also all of the DropDowns inside Column 1 how can I do that?
protected void triggerDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
// what should I do here?
}
Inside your event method you should access the DropDownList that resides within each row of the GridView. Doing this you can bind each DropDownList to whatever data you want.
This link shows you how to do that:
http://www.velocityreviews.com/forums/t191319-need-help-with-accessing-a-control-within-a-template-field.html
Basically:
Iterate over each row of your GridView;
Find the DropDownList control with something like:
DropDownList mddl = GridView.Rows[2].FindControl("myDropDown1");
Bind new data to mddl.
The gridview is very likely not what you want here. The way to change the value of a control contained in a row is usually through grabbing a handle to the desired control using e.Item.FindControl() from within the ItemDataBound event of the gridview.
The problem with your approach is that you're wanting a control outside of the gridview (triggerDropDown) to interact with a single row of the gridview. Do you want the first row, first column, last row, first column or first column for each of the items in the grid? It's probably better you take the target of your trigger dropdown and place it outside of the gridview and deal with it directly.
If you really intend to change items in a row in the grid consider doing so in the ItemDataBound event of the gridview and you'll find lots of examples out there.
Actually I can use GridViewRow :) I just have to find the GridViewControl and get its Rows attribute which is a GridViewRow and now I can do a foreach of each row.
foreach (GridViewRow gridViewRow in (this.FindControl("myGridView") as GridView).Rows)
{
// I can see all elements of my row here as if I am traversing on GridViewEvents
}

How do I data bind a drop down list in a gridview from a database table using VB?

So in this gridview, there is a column for status and I want to have a drop down list with Pass, Pending, Fail appear when the edit button is clicked. These values are already in a table, so I need to somehow bind from this table to each ddl for every row.
Here is the column from the gridview. As you can see, I would like to just have a label showing when not in edit mode, and a ddl when the edit button is pressed
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="Name"
datatextfield="Name" DataSource="*What goes here?*"> />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text='I don't understand how to get this from the ddl' />
</ItemTemplate>
</asp:TemplateField>
For clarity's sake, my table is named Status, and the database is named DirectImport
There's a few steps to go through here - none of them are particularly difficult, but they can be a bit fiddly (IMHO). The good news is once you've got this working once, it gets easier to do it again!
I'm assuming you've got a <asp:*DataSource> control on your page - my preference is for an ObjectDataSource but I don't think it matters, I think a SqlDataSource works equally well. I've never tried doing this with GridView.DataSource = MyDataSet in code-behind, so I don't know whether that would work or not, but my assumption is that it wouldn't as you wouldn't get the proper two-way binding that you want. This data source feeds your grid with your main data. The key point here is that your database query must return both the Status text field and the Status id.
So your gridview will now look something like:
<asp:objectdatasource runat="server" id="MainDataSource" ... />
<asp:gridview runat="server" id="MyGridView" DataSourceID="MainDataSource">
<Columns>
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text="<%# Bind('Status') %>" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
The Text="<%# Bind('Status') %>" is the bit you're missing to get the status text into the grid.
Now add a second data source into your markup that reads in the set of values from the Status table.
<asp:objectdatasource runat="server" id="StatusObjectDataSource" ... />
And add the EditItemTemplate into the GridView, which is bound to the Status DataSource.
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="StatusID"
datatextfield="Status" DataSourceID="StatusObjectDataSource"
SelectedValue="<%# Bind('StatusId') %>" />
</EditItemTemplate>
The SelectedValue="<%# Bind('StatusId') %>" is what connects up the two datasets so that when you flip a row into Edit mode, the dropdownlist has the correct item already selected, and when you then save it you've got the Status ID to put into your database.
And you're done.
I have used the RowDataBound event. Here is a small code snippet. HTH
you would have an ItemTemplate in your aspx/ascx
<asp:TemplateField HeaderText="Column Headings">
<ItemTemplate>
<asp:DropDownList ID="ddlName" runat="server" Width="150"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
and in your code behind, you will have
protected void grdDataMap_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("ddlName");
ddl.DataSource = someList;//the source of your dropdown
ddl.DataBind();
}
}
so when you bind your grid with grdDataMap.Databind (assuming your grid id is grdDataMap), row databound event will be called for each row (including header/footer, and thats the reason you check RowType)
so you can probably decide what controls/columns to hide/show/bind inside this row databound event
In the winforms world I pull my objects from the DB into a List(Of Whatever) and use the list as the datasource.
This also lets me add extra "convenience" fields in the object so that I can populate it with stuff from other tables.
I don't know asp.net at all so if you can do something similar, it might help.
A really quick solution is to create a custom web control for the status dropdown. The control will always contain the same data. When it renders you populate the datasource. When it gets added to the gridview, the data will be in the drop down. Hope that helps!

Resources