TextBox in GridView not holding its value on postback - c#

I have a gridview on a .NET forms application, and on postback, I am not seeing the values entered in the textbox within a gridview.
ASPX:
<asp:GridView ID="gvItems" runat="server" AutoGenerateColumns="false" ShowHeader="false" DataKeyNames="ItemId" EnableViewState="true">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="txtItem" runat="server" Text="0" EnableViewState="true" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ItemId" />
</Columns>
</asp:GridView>
<asp:Button runat="server" ID="btn" Text="Submit" OnClick="btn_OnClick" OnClientClick="javascript:return someClientStuff();" />
Code Behind:
protected void btn_OnClick(object sender, System.EventArgs e)
{
foreach(GridViewRow row in gvItems.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
var itemId = Convert.ToInt32(gvItems.DataKeys[row.RowIndex].Values[0]);
var itemValue = ((row.Cells[0].FindControl("txtItem") as TextBox).Text;
}
}
I am seeing itemId populated for each row, but itemValue is always empty string.
Been a while since I worked on a forms application, any help is appreciated!

I will assume that the DataBind of the GridView is not in if(!IsPostBack). Add this to the Page_Load
if(!IsPostBack)
{
gvItems.DataSource = soruceOftheGrid
gvItems.DataBind();
}

On the button click, try to store the values in the view state and within page load event, try to assign the viewstate back to the grid view as for each postback, page load event is called. Its good to assign the values back to grid view within page load, this will help you to retain the values you have entered.

Related

How do I modify edititemtemplate unbounded checkboxes before they are rendered(visible) in edit mode?

I have a unique situation. I have added several checkboxes to a gridview and they are populated from a database. They look very good in itemtemplate mode. When I click the Edit button and they are rendered, they loose all settings and appear is unchecked boxes. How do I populate the edititemtemplate checkboxes before they are displayed in edit mode?
Here is the code snippet in the aspx page:
<asp:TemplateField HeaderText="Referral">
<ItemTemplate>
<asp:CheckBox ID="CheckBox7" runat="server" />
</ItemTemplate>
<EditItemTemplate>
<asp:CheckBox ID="CheckBox10" runat="server" />
</EditItemTemplate>
</asp:TemplateField>
and here is the code behind for this checkbox that populates these itemtemplate checkboxes:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//load the referral column from the form3 data column to display the results
TextBox txtReferral = (TextBox)e.Row.FindControl("TextBox82"); //form1
if (txtReferral != null)
{
CheckBox ckbxReferral = (CheckBox)e.Row.FindControl("CheckBox7");
ckbxReferral.Enabled = false;
if (txtReferral.Text.Length > 0)
{
int intReferral = Convert.ToInt32(txtReferral.Text.ToString());
if (intReferral > 0)
{
if (!ckbxReferral.Checked)
{
ckbxReferral.Checked = true;
}
intReferral = 0;
}
}
}
}
I have tried to set the editemtemplate checkboxes, but have had no luck since they are currently null objects. I am a newbie to .net programming, so any help will be greatly appreciated. My ultimate goal is to use the results of the checkboxes to populate two additional child tables from these results.
You need to keep the id of the checkbox controls same in both itemtemplate and edititemtemplate:
<asp:TemplateField HeaderText="Referral">
<ItemTemplate>
<asp:CheckBox ID="CheckBox7" runat="server" />
</ItemTemplate>
<EditItemTemplate>
<asp:CheckBox ID="CheckBox7" runat="server" />
</EditItemTemplate>
</asp:TemplateField>

Dropdownlist selection doesn't persist data on AddRow button click

I have an editable GridView.
I have an AddRow button, which adds a row which consists of 3 text boxes and one dropdown list.
Also, I have a Delete button, which removes the whole row when clicked.
Whenever I click on AddRow button, the selection of my dropdownlist doesn't persist, the selected value is realigned to the very first item.
Below are the codes:
<asp:GridView ID="GridView1" runat="server" ShowFooter="true" AutoGenerateColumns="false"
OnRowDeleting="GridView1_RowDeleting">
<Columns>
<asp:TemplateField HeaderText="Serial No">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Container.DataItemIndex + 1 %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Col1">
<ItemTemplate>
<asp:TextBox runat="server" ID="txt1" Text='<%# Eval("Column1") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Col2">
<ItemTemplate>
<asp:TextBox ID="txt2" runat="server" Text='<%# Eval("Column2") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Col3">
<ItemTemplate>
<asp:TextBox ID="txt3" runat="server" Text='<%# Eval("Column3") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="DropDown">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataTextField='<%# Eval("Column4") %>'>
<asp:ListItem>London</asp:ListItem>
<asp:ListItem>Paris</asp:ListItem>
<asp:ListItem>New Delhi</asp:ListItem>
<asp:ListItem>New York</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="btnAddNewRow" runat="server" Text="AddRow" OnClick="Add" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Button" ShowDeleteButton="true" />
</Columns>
</asp:GridView>
<asp:Button ID="btnSavetoDB" runat="server" Text="save" OnClick="btnSavetoDB_Click" />
EDITED CODE:
List<string> newList = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var table = CreateDataTable();
table.Rows.Add("", "", "");
BindGridView(table);
}
}
//Called on AddRow button click
protected void Add(object sender, EventArgs e)
{
var newTable = PopulateTableFromGridView();
newTable.Rows.Add("", "", "");
BindGridView(newTable);
}
private DataTable PopulateTableFromGridView()
{
var table = CreateDataTable();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)GridView1.Rows[i].FindControl("txt1");
TextBox box2 = (TextBox)GridView1.Rows[i].FindControl("txt2");
TextBox box3 = (TextBox)GridView1.Rows[i].FindControl("txt3");
DropDownList ddl = (DropDownList)GridView1.Rows[i].FindControl("DropDownList1");
table.Rows.Add(box1.Text, box2.Text, box3.Text,ddl.SelectedItem.Text);
}
newList.Add(ddl.SelectedItem.Text);//add selecteditems to a global list
return table;
}
//Sets the first empty row to the grid view
private DataTable CreateDataTable()
{
var dt = new DataTable
{
Columns = { "Column1", "Column2", "Column3","Column4" }
};
return dt;
}
private void BindGridView(DataTable table)
{
GridView1.DataSource = table;
GridView1.DataBind();
for(int i=0;i<GridView1.Rows.Count-1;i++)
{
DropDownList ddl2=(DropDownList)GridView1.Rows[i].FindControl("DropDownList1");
ddl2.ClearSelection();
ddl2.Items.FindByText(newList[i]).Selected = true;
}
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
var dt = PopulateTableFromGridView();
if (dt.Rows.Count > 1)
{
dt.Rows[e.RowIndex].Delete();
}
BindGridView(dt);
}
The first screenshot, I have selected NewDelhi from the dropdownlist, which is the 3rd item:
The second screenshot, wherein a new row has been added after AddRow button is clicked, the dropdownlist is realigned in the first row, shows London.
How to make the code persist the dropdownlist selection when AddRow and Delete button is clicked?
I tried disabling the AutoPostBack property of the dropdownlist to false, but to no effect.
Experts please help.
SUCCESSFUL SCREENSHOTS:
I have solved the problem after some R&D.
I have created a new instance of dropdownlist after the gridview is bound, and in that new instance, I am preserving the previous selection using a List from the PopulateGridView method.
Please see the edit of the code.
Hope this helps some body.
Every time you hit the addrow button you are performing a postback.
every postback rebuilds then entire page including the grid based on your table. You can see that in your own code.
But part of this is that the controls within each row are rebuilt too. This includes your DDL's, but you are not saving/restoring the selected values from each drop down. More correctly, the selected values are saved but are invalidated when you recreate the table. you have to handle the RowDatabound event and in each row restore the selected value in the ddl.
But you may have a bigger problem. You are using the same instance of the DDL in each row. this may cause selection/persistence issues. If you find that selecting an item from the ddl causes all rows to have the same selected item, that's the problem in action.
Take a look at the rendered output for your ddl's and make sure the id's are unique for each row.
if the ddl has it's own datasource then you need to create a new instance of a DropDownlist in each row and assign it the same datasource rather than using find control.
if the control has it's list items hard coded then you should just check for unique ddl id's

Checked state of RadioButtons in GridView don't change after postback

I have a Gridview control and I have placed a RadioButton in the itemtemplate. When I click a button I'm trying to get the checked property of the radio button. But When I click the checked property is always returning false. Please look into the below code and let me know where I'm making mistake.
aspx Code
<asp:GridView ID="gvDepartments" runat="server" AutoGenerateColumns="False" GridLines="None"AllowPaging="true" CssClass="mGrid" PagerStyle-CssClass="pgr" AlternatingRowStyle-CssClass="alt">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton ID="rdbtn" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Label ID="lbl" runat="server"></asp:Label>
<asp:Button ID="btn" runat="server" Text="Save" OnClick="btn_Click" CssClass="button small"/>
Code Behind on button click
foreach (GridViewRow row in gvDepartments.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
RadioButton rd = (RadioButton)row.FindControl("rdbtn");
lbl.Text += rd.Checked.ToString();// +rd1.Checked.ToString();
}
}
Result will be False always in the label always. I'm using Ajaxcontroltoolkit in the application, Above controls are present in the update panel and I even tried to placing button and event in the triggers but the result is same. Please help.
Regards,
Nuthan A R
When do you assign and load the DataSource of the GridView? Note that you should do that only if(!IsPostBack) and not on every postback. So use the Page.IsPostBack property.
So assuming that you're using Page_Load for this:
protected void Page_Load(Object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
DataBindGridView(); // method that assigns DataSource and calls DataBind
}
}

Button in a GridView to open in a new Window(ASP.Net 3.5)

I have a gridview in my ASPX page. This GridView is inside a UpdatePanel which causes partial page postbacks.
I have a button as the last column for each row in the GridView. How do I open temp.aspx page with ID value passed to it onClick of each button. I have a ID column in the gridView too.
Please help
You can get the DataSource for each row OnRowDataBound, then find the control you want in that row and apply your OnClick JavaScript:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Example"
<ItemTemplate>
<asp:label ID="YourSpanToClick" runat="server" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label yourSpanToClick= (Label)e.Row.FindControl("YourSpanToClick");
YourDataSrcRowObject rowObject= DataBinder.Eval(e.Row.DataItem) as YourDataSrcRowObject ;
string js = String.Format("window.open('{0}');", "temp.aspx?Id=" + rowObject.Id)
yourSpanToClick.Attributes.Add("onclick",js);
}
}
You can't open an new window from OnClick event. Try the OnClientClick inside the RowDataBound event of that gridview.
Private Sub DataGridView1_OnRowDataBound(Sender as Object, e as DataGridView.EventArgs)
Dim btn as Button=e.Row.FindControl("btnName")
btn.OnClientClick="javascript:window.open(""temp.aspx?id=22"")
End Sub
Something like this.

DataBind User Controls in Gridview

I got a GridView in ASP.Net in which a user control is placed:
<asp:GridView ID="GVWunitcollection"
CssClass="gridview"
runat="server"
ShowHeader="false"
ShowFooter="false"
AutoGenerateColumns="False">
<HeaderStyle CssClass="headerstyle" />
<RowStyle CssClass="rowstyle row" />
<FooterStyle CssClass="rowstyle row" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<uc:Unit ID="UNTcol" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I bind the GridView to a List<T> filled with custom 'Unit' Classes. Each Unit consists of several properties to fill the usercontrol. (The user control holds a table, and some labels and textboxes).
How can I achieve this? Is there a simple way to bind each usercontrol to the appropriate Unit?
By the way, this is my way to mimic a "dynamic" behavior of multiple usercontrols on a page. If there's a more simple way, I would like to know how!
thank you!
You should handle the OnRowDataBound event then use FindControl and the DataItem property on the event argument to extract the data you are binding to. You should expose properties on the user control to assign values to. Here is an example:
<asp:GridView ID="gvTest" runat="server" EnableViewState="false"
OnRowDataBound="gvTest_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblTest" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
protected void Page_Load(object sender, EventArgs e)
{
gvTest.DataSource = new[] { 1, 2, 3, 4 };
gvTest.DataBind();
}
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int item = (int)e.Row.DataItem;
Label lblTest = (Label)e.Row.FindControl("lblTest");
lblTest.Text = item.ToString();
}
}
Instead of int you should cast to your specific datatype and instead of Label you should cast to your user control type. Instead of the Label's Text property you should assing to the property you've exposed from your user control.
You could create public properties on your usercontrol and assign them values in the gridview's OnRowDataBound event.
I have a post that outlines how I handle dynamic usercontrols here
Hope that helps!

Categories