Gridview is not displaying while i run my code - c#

I want to display three column field as dropdownlist and other in textbox format.I have wrote the code to display the dropdownlist value from my database but its not working.I have attached my code for your referal
<asp:GridView ID="Gv1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="FacultyName">
<ItemTemplate>
<asp:Label ID="lblfaculty" runat="server" Text='<%%# Eval("facultyname") %>>' Visible="false" />
<asp:DropDownList ID="ddlfaculty" runat="server" OnSelectedIndexChanged="ddlfaculty_SelectedIndexChanged"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Subject">
<ItemTemplate>
<asp:Label ID="lblsubject" runat="server" Text='<%%# Eval("subject") %>>' Visible="false" />
<asp:DropDownList ID="ddlsubject" runat="server" OnSelectedIndexChanged="ddlsubject_SelectedIndexChanged"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Subject">
<ItemTemplate>
<asp:Label ID="lblsubject" runat="server" Text='<%%# Eval("subject") %>>' Visible="false" />
<asp:DropDownList ID="ddlsubject" runat="server" OnSelectedIndexChanged="ddlsubject_SelectedIndexChanged1"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblsubject" runat="server" Text='<%%# Eval("sethour") %>>' Visible="false" />
<asp:TextBox ID="ddlsethour" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblcount" runat="server" Visible="false" />
<asp:TextBox ID="Count" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CodeBehind:
public partial class transhonorarium : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ddlfaculty_SelectedIndexChanged(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
SqlDataAdapter cmd = new SqlDataAdapter("select facultyname from faculty", con);
DataTable dt = new DataTable("dt");
cmd.Fill(dt);
Gv1.DataSource = dt;
Gv1.DataBind();
}
}
protected void ddlsubject_SelectedIndexChanged(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
SqlDataAdapter cmd = new SqlDataAdapter("select subject from assign where facultyname=#facultyname", con);
DataTable dt = new DataTable("dt");
cmd.Fill(dt);
Gv1.DataSource = dt;
Gv1.DataBind();
}
}
}

You need to change one thing here.
AutoGenerateColumns = true. Because of this, you will be able to see the columns assigned and its data.
Secondly,
You need to Bind your Gridview as required on Page_load or somewhere you want. Here is for page load.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Gv1.DataSource = Somesource;
Gv1.DataBind();
}
}
See the Bind Data
public void BindData()
{
SqlCommand comd = new SqlCommand("SELECT * FROM Yourtablename", con);
SqlDataAdapter da = new SqlDataAdapter(comd);
DataTable dt = new DataTable();
da.Fill(dt);
GV1.DataSource = dt;
GV1.DataBind();
}
Hope that helps

Call the DataBind() Method of your Gridview when your data changes.
I'd do something like this:
protected override void OnPreRender(Eventargs e)
{
base.OnPreRender(e);
GV1.DataBind();
}

in order to fill your dropdown lists ,you should implement _RowDataBound event and to update dataset bases on your selection you should also implement RowCommand event for your dropdown objects.
btw. in ddlsubject_SelectedIndexChanged, you also need to add parameter to your sql command to get your sql string working ,
hope this helps.

Related

Not properly set Data in GridView

i'm trying retrieve data from database and dispay in gridview. for create Header i'm using HeaderTemplet Tag. but in gridview always first column of employee id is blank.
my code is as under of aspx page:
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" Width="99%" GridLines="Both" OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<tr>
<th style="padding: 2.5px; width: 10%;" >eid</th>
<th style="padding: 2.5px; width: 55%;" >First Name</th>
<th style="padding: 2.5px;" >Last Name</th>
</HeaderTemplate>
</asp:TemplateField>
<asp:BoundField DataField="idemp" />
<asp:BoundField DataField="fname" />
<asp:BoundField DataField="lname" />
<asp:TemplateField>
<ItemTemplate>
<asp:GridView ID="GridView2" runat="server" Width="99%" GridLines="Both" AutoGenerateColumns="false" CssClass="ChildGrid">
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
code behind:
namespace WebApplication2
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Populate the GridView.
bindGridview();
}
}
public void bindGridview()
{
DataTable dt = new DataTable();
string constr = #"server=127.0.0.1;user id=root;pwd=n0711p2010p;database=emp";
using (MySqlConnection con = new MySqlConnection(constr))
{
MySqlCommand cmd = new MySqlCommand("select idemp,fname,lname from emp", con);
con.Open();
MySqlDataReader dtreader = cmd.ExecuteReader();
dt.Load(dtreader);
if (dt.Rows.Count >0)
{
GridView1.DataSource = dt;
GridView1.DataBind();
con.Close();
}
}
}
//RowDataBound Event
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//Checking the RowType of the Row
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = new DataTable();
string constr = #"server=127.0.0.1;user id=root;pwd=n0711p2010p;database=emp";
using (MySqlConnection con = new MySqlConnection(constr))
{
con.Open();
GridView child_gridview = (GridView)e.Row.FindControl("GridView2");
String CountryId = (e.Row.RowIndex+1).ToString();
MySqlCommand cmd = new MySqlCommand("select salary,post from emp where idemp="+CountryId, con);
MySqlDataReader dtreader = cmd.ExecuteReader();
dt.Load(dtreader);
if (dt.Rows.Count > 0)
{
child_gridview.DataSource = dt;
child_gridview.DataBind();
}
}
}
}
}
}
and output is as under:
first column of gridview is always empty.when using HeaderTemplet tag.
and i want to achieve like this.
If you want the nested GridView to span multiple columns, you have to do that in the RowDataBound of the parent GridView. In there you can set the colspan and remove the last 2 cells.
So if you have a GridView
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Id">
<ItemTemplate>
<%# Eval("Id") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<%# Eval("Name") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Saldy">
<ItemTemplate>
<asp:GridView ID="NestedGrid" runat="server" AutoGenerateColumns="true">
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Address">
</asp:TemplateField>
<asp:TemplateField HeaderText="City">
</asp:TemplateField>
</Columns>
</asp:GridView>
And the RowDataBound event
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a normal datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//cast the row back to a datarowview
DataRowView row = e.Row.DataItem as DataRowView;
//use findcontrol to locate the nested gridview
GridView gv = e.Row.FindControl("NestedGrid") as GridView;
//bind data to the nested grid
gv.DataSource = source;
gv.DataBind();
//set the column span to 3 on the cell that has the nested gridview
e.Row.Cells[2].ColumnSpan = 3;
//hide the last 2 cells
e.Row.Cells[3].Visible = false;
e.Row.Cells[4].Visible = false;
}
}
The only problem is that the cells of the parent and child do not match in width, so you may need to set a fixed width for those columns.
Seems like you are retrieving the data just fine but not displaying it properly.
You are mistakenly using TemplateField to define headers.
You can simply do the following:
<asp:GridView ID="GridView1" runat="server" Width="99%" GridLines="Both" OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="idemp" headertext="Employee ID" />
<asp:BoundField DataField="fname" headertext="First Name" />
<asp:BoundField DataField="lname" headertext="Last Name" />
</Columns>
</asp:GridView>
As you can see the Header names are defined right in bound column.
Enjoy, and let me know if still having issue

GridView in LoginView giving wrong row count

I have a GridView within a LoginView that I am getting an Index Out Of Range error with. When I display the # of rows in the GridView it always shows 0 which is causing this error.
Is there something specific that I need to be doing to get a GridView
to properly work within a LoginView?
Below is the code that is being run when I click on a button in the GridView and the error only comes up on the GridView row = gv.Rows[e.RowIndex]; line. If I use only e.RowIndex I do not get the error and it will actually return the proper number. If I do gv.DataKeys.Count it will return the correct count. If I do gv.Rows.Count it will always be 0. I think it has something to do with a PostBack because if I do a row count in my page_load then it returns the correct count. Please let me know if there is anything else that you need for me to post?
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
try
{
GridView gv = ReviewLoginView.FindControl("gvReview") as GridView;
GridViewRow row = gv.Rows[e.RowIndex];
string Id = (row.FindControl("lblID") as Label).Text;
string constr = System.Configuration.ConfigurationManager.AppSettings["ObservationCardCS"];
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("cardReview"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", Id);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
gv.EditIndex = -1;
this.BindGrid();
}
catch (Exception ex)
{
GridView gv = ReviewLoginView.FindControl("gvReview") as GridView;
int index = e.RowIndex;
lblError.ForeColor = System.Drawing.Color.Red;
lblError.Text = ex.Message + " " + index.ToString() + " " + gv.Rows.Count;
}
}
Below is the LoginView from the aspx page.
<asp:LoginView runat="server" ViewStateMode="Disabled" ID="ReviewLoginView">
<LoggedInTemplate>
<%--<AnonymousTemplate>--%>
<div>
<asp:GridView ID="gvReview" runat="server" AutoGenerateColumns="false" DataKeyNames="ID"
OnRowDataBound="OnRowDataBound" OnRowDeleting="OnRowDeleting" EnableViewState="true"
EmptyDataText="No records have been added." AllowSorting="true" ShowHeaderWhenEmpty="true"
AlternatingRowStyle-BackColor="#e0e0e0" HeaderStyle-BackColor="#d0d0d0" ViewStateMode="Disabled"
EnableSortingAndPagingCallbacks="false">
<Columns>
<asp:TemplateField HeaderText="ID" ShowHeader="false" Visible="true">
<ItemTemplate>
<asp:Label ID="lblID" runat="server" Text='<%# Bind("ID") %>' CssClass="cmsID"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="User">
<ItemTemplate>
<asp:Label ID="lblSubmittedBy" runat="server" Text='<%# Eval("submittedBy") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Location">
<ItemTemplate>
<asp:Label ID="lblLocation" runat="server" Text='<%# Eval("location") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Date">
<ItemTemplate>
<asp:Label ID="lblSubmittedDate" runat="server" Text='<%# Eval("submittedDate") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="What Was Observed?">
<ItemTemplate>
<asp:Label ID="lblWhatWasObserved" runat="server" Text='<%# Eval("whatWasObserved") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="What Action Was Taken?">
<ItemTemplate>
<asp:Label ID="lblWhatActionWasTaken" runat="server" Text='<%# Eval("whatActionWasTaken") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="What Agreement Was Reached?">
<ItemTemplate>
<asp:Label ID="lblWhatAgreementWasReached" runat="server" Text='<%# Eval("whatAgreementWasReached") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Edit">
<ItemTemplate>
<asp:Button ID="btnSubmit" runat="server" Text="Edit" CssClass="editbutton" />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="Review" ButtonType="Button" ShowDeleteButton="true" DeleteText="Review" />
</Columns>
</asp:GridView>
</div>
</LoggedInTemplate>
<%--</AnonymousTemplate>--%>
<AnonymousTemplate>
You must login to view submitted Observation Cards.
</AnonymousTemplate>
</asp:LoginView>
Below is the BindGrid()
private void BindGrid()
{
try
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["ObservationCardCS"]);
{
SqlCommand comm = new SqlCommand("cardSelectNew2", conn);
SqlDataAdapter sda = new SqlDataAdapter();
sda.SelectCommand = comm;
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.AddWithValue("#Begin", "1/1/1950");
comm.Parameters.AddWithValue("#End", "12/31/2049");
comm.Parameters.AddWithValue("#Reviewed", "0");
comm.Parameters.AddWithValue("#OrderBy", "CH.id");
comm.Parameters.AddWithValue("#AscDesc", "Asc");
comm.Parameters.AddWithValue("#DateRange", "Last 30 Days");
comm.Connection = conn;
sda.SelectCommand = comm;
DataTable dt = new DataTable();
sda.Fill(dt);
GridView gv = ReviewLoginView.FindControl("gvReview") as GridView;
gv.DataSource = dt;
gv.DataBind();
}
}
catch (Exception ex)
{
lblError.ForeColor = System.Drawing.Color.Red;
lblError.Text = ex.Message;
}
}
Below is my page_load
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.BindGrid();
lblError.ForeColor = System.Drawing.Color.Black;
lblError.Text = "";
}
}
You are on the right track! But without seeing the whole class and markup we can only speculate.
Check that you are not clearing or rebuilding the data on the page load event handler, if the Grid and datasource is defined in the markup then it should cache or requery the data between page postbacks, check that you have set EnableRowCache on the GridView so that you dont have to re-query for the data during postbacks.
It looks like you are using the #OldSchool BindGrid() data load pattern, perhaps the simplest solution may be to ensure that the data is loaded first by calling BindGrid before you try to access the rows:
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
this.BindGrid();
try
{
... delete logic
this.BindGrid(); // re-load after the change
}
catch (Exception ex)
{
...
}
}
Without enabling the row cache though you have to ensure that the same data is loaded into the grid in the same order or delete logic like this based on row index (instead of the primary key of the row) could result in you deleting the wrong data row.

Why is my data not showing in my GridView? [duplicate]

This question already exists:
how to show data in gridview from arraylist in asp.net?
Closed 8 years ago.
I have a database where there is userid, problemname and status column. I am retrieving this data from database in an ArrayList and returning it. Now to show in GridView I have taken a DataTable and in the DataTable I have put three columns and I just want to show my data that is saved in the ArrayList in these columns by making one row.
Here is my code:
protected void Page_Load(object sender, EventArgs e)
{
ArrayList myArrayList = ConvertDataSetToArrayList();
// Display each item of ArrayList
DataTable dt = new DataTable();
dt.Columns.Add("User Id");
dt.Columns.Add("Problem Name");
dt.Columns.Add("Status");
foreach (Object row in myArrayList)
{
dt.Rows.Add();
dt.Rows[dt.Rows.Count - 1]["User Id"] = ((DataRow)row)["userid"].ToString();
dt.Rows[dt.Rows.Count - 1]["Problem Name"] = ((DataRow)row) ["problemname"].ToString();
dt.Rows[dt.Rows.Count - 1]["Status"] = ((DataRow)row)["status"].ToString();
}
GridView1.DataSource =dt;
GridView1.DataBind();
}
public ArrayList ConvertDataSetToArrayList()
{
string con = " ";
con = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
SqlConnection objsqlconn = new SqlConnection(con);
objsqlconn.Open();
SqlCommand cmd = new SqlCommand("SELECT userid,problemname,status FROM problemtable", objsqlconn);
cmd.ExecuteNonQuery();
cmd.CommandType = CommandType.Text;
SqlDataAdapter myAdapter = new SqlDataAdapter();
myAdapter.SelectCommand = cmd;
DataSet myDataSet = new DataSet();
myAdapter.Fill(myDataSet);
ArrayList myArrayList = new ArrayList();
foreach (DataRow dtRow in myDataSet.Tables[0].Rows)
{
myArrayList.Add(dtRow);
}
objsqlconn.Close();
return myArrayList;
}
Here is my html:
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" >
<Columns>
<asp:TemplateField HeaderText="cdd">
<ItemTemplate>
<asp:CheckBox ID="CheckBox2" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
Why is my data is not showing in my GridView?
You need to bind your data to specific controls in your gridview. For example, you need to have labels in your gridview itemtemplate to bind your data to. Here is an example:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" >
<Columns>
<asp:TemplateField HeaderText="cdd">
<ItemTemplate>
<asp:CheckBox ID="CheckBox2" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="User Id">
<ItemTemplate>
<asp:Label ID="lbl_userid" runat="server" Text='<%# Eval("User Id") %>' CssClass="lbl"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Problem Name">
<ItemTemplate>
<asp:Label ID="lbl_problemname" runat="server" Text='<%# Eval("Problem Name") %>' CssClass="lbl"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="status">
<ItemTemplate>
<asp:Label ID="lbl_status" runat="server" Text='<%# Eval("Status") %>' CssClass="lbl"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I agree that an ArrayList is a poor choice, but, regardless of how you're binding the data, you need to tell the gridview what it's supposed to show. You can do this using inline tags or by using an onitemdatabound trigger. I recommend you look up some more examples of gridviews.

Accessing HiddenField inside the datalist

I'm using a Datalist to show countries list each record having a Gridview containing a list of states and each state having a Dropdownlist for cities. I am using a hidden field to get the ID of country to retrieve the name of state for every record by using Eval("C_ID") in the hidden field. But it raises ArgumentOutOfRangeException. I'm not able to know what I'm doing wrong.
Here is the code for Datalist:
<asp:DataList ID="DataList1" runat="server" RepeatColumns="4" RepeatDirection="Horizontal" onitemdatabound="DataList1_ItemDataBound" >
<ItemTemplate>
<table border="1px">
<tr>
<td>
<%#Eval("C_Name") %><br />
<asp:HiddenField ID="HiddenField1" Value='<%#Eval("C_ID") %>' runat="server" />
<asp:GridView ID="GridView1" AutoGenerateColumns="false" runat="server">
<Columns>
<asp:TemplateField HeaderText="State Cities">
<ItemTemplate >
<asp:CheckBox ID="CheckBox1" runat="server" />
<%#Eval("S_Name") %>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
and this is code behind:
public partial class AdvancedTable : System.Web.UI.Page
{
SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString);
DataSet ds = new DataSet();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand("select * from Country", con);
con.Open();
da.Fill(ds, "Country");
con.Close();
DataList1.DataSource = ds;
DataList1.DataBind();
}
}
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
SqlDataAdapter da2 = new SqlDataAdapter();
da2.SelectCommand = new SqlCommand("select * from State where C_ID='"+((HiddenField)DataList1.Items[e.Item.ItemIndex].FindControl("HiddenField1")).Value+"'",con);
con.Open();
da2.Fill(ds, "State");
con.Close();
((GridView)e.Item.FindControl("GridView1")).DataSource = ds.Tables["State"];
((GridView)e.Item.FindControl("GridView1")).DataBind();
}
}
Perhaps, instead of DataList1.Items[e.Item.ItemIndex].FindControl("HiddenField1")
Just use e.Item.FindControl("HiddenField1")
Instead, you can do the following:
<asp:DropDownList ID="DropDownList1" runat="server" DataSource="<%# GetList((int)Eval("C_ID"))%>">
</asp:DropDownList>
In the code Behind
protected DataTable GetList(int id){ }

Gridview binding clears unexpectedly

I have a problem with my gridview. I have searched alot for the solution but can't find any answers. I think I have located the problem to be that the gridview is no longer bound when I press the update button - which results in null values. I thought it was enough to bind at RowEditing. Where else can I bind my gridview?
See the markup below:
<asp:GridView ID="ProductGridView" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" DataKeyNames="Id" OnRowEditing="ProductGridView_RowEditing"
OnRowCancelingEdit="ProductGridView_RowCancelingEdit" OnRowUpdating="ProductGridView_RowUpdating"
OnRowDeleting="ProductGridView_RowDeleting" OnDataBound="ProductGridView_DataBound" OnRowDataBound="ProductGridView_RowDataBound">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" CausesValidation="false" />
<asp:TemplateField HeaderText="Name" SortExpression="Name">
<EditItemTemplate>
<asp:TextBox ID="txtName" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity" SortExpression="Quantity">
<EditItemTemplate>
<asp:TextBox ID="txtQuantity" runat="server" Text='<%# Bind("Quantity") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblQuantity" runat="server" Text='<%# Eval("Quantity") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Family" SortExpression="Family.Name">
<EditItemTemplate>
<asp:DropDownList ID="ddlFamily" runat="server" OnInit="ddlFamily_Init">
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblFamily" runat="server" Text='<%# Eval("Family.Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindGridView(_productRepo.GetAll());
}
}
private void BindGridView(object source)
{
ProductGridView.DataSource = source;
ProductGridView.DataBind();
}
protected void ProductGridView_RowEditing(object sender, GridViewEditEventArgs e)
{
ProductGridView.EditIndex = e.NewEditIndex;
BindGridView(_productRepo.GetAll()); // GetAll returns an IEnumerable.
rowCount = ProductGridView.Rows.Count; // Count is 6 here, which is correct.
}
protected void ProductGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
rowCount = ProductGridView.Rows.Count; // Count is 0 here.
//BindGridView(_productRepo.GetAll()); // Tried to rebind which works but getting the old values obviously.
//rowCount = ProductGridView.Rows.Count; // Count is 6 here.
// Get the controls - all is null. Works ok when I use BindGridView above.
TextBox txtName = FindChildControl<TextBox>(this.Page, "txtName");
TextBox txtQuantity = FindChildControl<TextBox>(this.Page, "txtQuantity");
DropDownList ddlFamily = FindChildControl<DropDownList>(this.Page, "ddlFamily");
// More code to populate a new product and bind the gridview again etc.
}
I also have a RowDataBound method. Can this contribute to the problem?
protected void ProductGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && (e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("ddlFamily");
ddl.DataSource = _familyRepo.GetAll().Select(f => f.Name);
ddl.DataBind();
Product product = _productRepo.FindSingle(p => p.Id == (int)ProductGridView.DataKeys[e.Row.RowIndex].Value);
ddl.SelectedIndex = (int)product.FamilyID - 1;
}
}
If I understand you correctly, you are saying your form controls within your datagrid disappear or reset to their initial state after postback.
The reason this is happening is because you are binding your grid in the Page_Load method, which comes too late in the page lifecycle to restore the control values. Your grid doesn't load until AFTER the LoadViewstate and LoadPostbackData events are fired and therefore, your grid's controls are loaded with their original state every time a postback is made.
I'd guess you're familiar with the asp.net lifecycle, but if not here is an article: http://msdn.microsoft.com/en-us/library/ms972976.aspx. I've dealt with this issue many times, and it took me awhile to fully understand what was going on here.
One solution to the problem is to load the grid in the overridden OnInit method, which occurs before the control data is restored. Something like this should work:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
BindGridView(_productRepo.GetAll());
}
I usually do data binding this way.... try this function and call it in your page load and other functions where you need it.
protected void bind()
{
con.Open();
SqlCommand cmd = new SqlCommand("Your Query", con);
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(ds);
gvCourse.DataSource = ds;
gvCourse.DataBind();
con.Close();
}
Or you can simply replace the !Page.IsPostBack with !IsPostBack
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGridView(_productRepo.GetAll());
}
}

Categories