In my gridview I have multiple pages.
I can select one or more items from Page 1 and save it in sql database.
However, If I select one item from Page 1 and another item from Page 2, system only save item from Page 1.
aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (Session["UserName"].ToString() != null)
{
SUserName.Text = Session["UserName"].ToString();
SUserEmail.Text = Session["Email"].ToString();
}
if (!Page.IsPostBack)
{
LoadUserSubSection();
CurrentDate();
this.SearchItems();
}
}
protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onmouseover", "MouseEvents(this, event)");
e.Row.Attributes.Add("onmouseout", "MouseEvents(this, event)");
}
//added in
GridViewRow gvr = e.Row;
if (gvr.RowType == DataControlRowType.DataRow)
{
CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
if (chkSelect != null)
{
int StID = Convert.ToInt32(gvItemDesc.DataKeys[gvr.RowIndex]["StID"]);
chkSelect.Checked = this.StItemDescIDs.Contains(StID);
}
}
}
private void SearchItems()
{
using (SqlConnection con = new SqlConnection(cs))
{
using (SqlCommand cmd = new SqlCommand())
{
string sql = "SELECT [StID],[StNo],[StItemDesc],[CreatedBy] FROM [StationeryRequest].
[dbo].[tblStationeryItemlist]";
if (!string.IsNullOrEmpty(txtSearch.Text.Trim()))
{
sql += " WHERE StItemDesc LIKE #StItemDesc + '%'";
cmd.Parameters.AddWithValue("#StItemDesc", txtSearch.Text.Trim());
}
cmd.CommandText = sql;
cmd.Connection = con;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
sda.Fill(dt);
gvItemDesc.DataSource = dt;
gvItemDesc.DataBind();
}
}
}
}
private List<int> StItemDescIDs
{
get
{
if (this.ViewState["StItemDescIDs"] == null)
{
this.ViewState["StItemDescIDs"] = new List<int>();
}
return this.ViewState["StItemDescIDs"] as List<int>;
}
}
protected void SelectDeselect(object sender, CommandEventArgs e)
{
foreach (GridViewRow gvr in gvItemDesc.Rows)
{
CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
if (chkSelect != null)
{
chkSelect.Checked = e.CommandName.Equals("SelectAll");
}
}
}
protected void OnPaging(object sender, GridViewPageEventArgs e)
{
//added in
foreach (GridViewRow gvr in gvItemDesc.Rows)
{
CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
if (chkSelect != null)
{
int StID = Convert.ToInt32(gvItemDesc.DataKeys[gvr.RowIndex]["StID"]);
if (chkSelect.Checked && !this.StItemDescIDs.Contains(StID))
{
this.StItemDescIDs.Add(StID);
}
else if (!chkSelect.Checked && this.StItemDescIDs.Contains(StID))
{
this.StItemDescIDs.Remove(StID);
}
}
}
gvItemDesc.PageIndex = e.NewPageIndex;
this.SearchItems();
}
protected void Search(object sender, EventArgs e)
{
this.SearchItems();
}
submit btn
protected void btnSubmit(object sender, EventArgs e)
{
object id;
//insert into Main Parent table -> tblStationeryRequest
string insertCmdtblStationeryRequest = "INSERT INTO tblStationeryRequest
(Department,RequestFor,UserName,Date,Email,Status) " +
"output inserted.StReqID " + //Get auto increment for StReqID
"VALUES (#Department,#RequestFor,#UserName,#Email,#Date,#Status)";
string Status = "Pending";
using (SqlConnection conn = new SqlConnection(cs))
{
conn.Open();
using (SqlCommand sqlcmd = new SqlCommand(insertCmdtblStationeryRequest, conn))
{
sqlcmd.Parameters.AddWithValue("#Department", ddlDept.SelectedItem.Text);
sqlcmd.Parameters.AddWithValue("#RequestFor", ddlName.SelectedItem.Text);
sqlcmd.Parameters.AddWithValue("#Date", lblCurrentDate.Text);
sqlcmd.Parameters.AddWithValue("#UserName", SUserName.Text);
sqlcmd.Parameters.AddWithValue("#Email", SUserEmail.Text);
sqlcmd.Parameters.AddWithValue("#Status", Status);
//get id from auto increment and will be used it in Child tables -> tblItemRequest,
tblSupplierRequest and so on.
//sqlcmd.ExecuteNonQuery();
id = sqlcmd.ExecuteScalar(); //the result is of Object type, cast it safely
}
}
Debug.WriteLine(id.ToString()); // Access it like this
string lblStID = "";
foreach (GridViewRow row in gvItemDesc.Rows)
{
CheckBox status = (row.Cells[1].FindControl("chkSelect") as CheckBox);
if (status.Checked)
{
if (lblStID != "")
{
lblStID += ",";
}
lblStID += (row.Cells[1].FindControl("chkSelect") as CheckBox).Text;
}
}
//In Page 1, can select one or more items
//However Page 1 one item and Page 2 one time, it only save from Page 1
string insertCmdtblRequestItemListID = "INSERT INTO tblRequestItemListID(StReqID, StID,
StItemDesc) select " + id.ToString() + ",StID,StItemDesc from tblStationeryItemlist where
StID in (" + lblStID + ")";
using (SqlConnection conn = new SqlConnection(cs))
{
conn.Open();
using (SqlCommand sqlcmd = new SqlCommand(insertCmdtblRequestItemListID, conn))
sqlcmd.ExecuteNonQuery();
}
.aspx
Here is my Gridview
< asp:GridView ID = "gvItemDesc" runat = "server" AutoGenerateColumns = "false"
AllowPaging = "true" DataKeyNames = "StID" OnPageIndexChanging = "OnPaging"
OnRowDataBound = "RowDataBound" Font - Size = "11pt" >
< Columns >
< asp:TemplateField >
< HeaderTemplate >
//no need use Check all function
< asp:CheckBox ID = "checkAll" runat = "server" Text = '<%#Eval("StID") %>' onclick
="checkAll(this);" />
</ HeaderTemplate >
< ItemTemplate >
< asp:CheckBox ID = "chkSelect" runat = "server" Text ='<%# Eval("StID") %>' onclick =
"Check_Click(this)" />
</ ItemTemplate >
</ asp:TemplateField >
< asp:BoundField DataField = "StID" HeaderText = "StID" ItemStyle - Width = "150"
SortExpression = "StID" Visible = "false" />
< asp:BoundField DataField = "StItemDesc" HeaderText = "Item Description" ItemStyle -
Width = "150" />
<asp:TemplateField HeaderText = "" >
</ asp:TemplateField >
< asp:TemplateField HeaderText = "" >
< ItemTemplate >
< asp:Label ID ="lblStItemDesc" runat = "server" Text = '<%# Eval("StItemDesc") %>'
Visible ="false" > </ asp:Label >
</ ItemTemplate >
</ asp:TemplateField >
</ Columns >
</ asp:GridView >
Ok, you have two approaches here.
First up, you can just during navigation, or filter, or paging have the user select data, and UPDATE the database (unless that's what you really want???).
What you want:
User can select any old row on the page. Maybe page around for fun, select a few more rows.
At that point, you THEN can process the rows selected and UPDATE the actual database.
So, we want to "separate" these two concepts to be crystal clear in your mind.
Next up:
We have two practical choices. We suffer a post back for the check box in the grid. I often use this, and it not all that bad.
If you REALLY want to avoid that post back, then on both paging event, and your final submit button, you have to "manage" that checked list.
Lets go with Mr. Easy. And if you really need the 2nd approach, then I can post a solution, but no need to do extra work when/if you don't need as such.
So, our simple grid - NOTE how the check box is un-bound - no data source.
So, our grid:
<asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" AllowPaging="true"
OnPageIndexChanging="GVHotels_PageIndexChanging" OnRowDataBound="GVHotels_RowDataBound">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="To Process" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="chkSel" runat="server" CssClass="bigcheck"
OnCheckedChanged="chkSel_CheckedChanged"
AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="GridPager" />
</asp:GridView>
<asp:Button ID="cmdProcess" runat="server" Text="Process selected" CssClass="btn" OnClick="cmdProcess_Click" />
<br />
Code to fill grid:
List<int> MySelList = new List<int>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadGrid();
ViewState["MySelect"] = MySelList;
}
else
MySelList = (List<int>)ViewState["MySelect"];
}
void LoadGrid()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * FROM tblHotels " +
"WHERE Description is not null " +
"ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
GVHotels.DataSource = rst;
GVHotels.DataBind();
}
}
}
and we now have this:
Ok, so now we need two extra routines.
The code to add/remove the selected check from the list (that we persisted).
That check box has auto post-back = true, and thus the code for that check box is this simple stub:
protected void chkSel_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
GridViewRow gRow = (GridViewRow)chk.Parent.Parent;
int pkID = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
if (chk.Checked)
{
// add to sel list
if (!MySelList.Contains(pkID))
MySelList.Add(pkID);
}
else
MySelList.Remove(pkID);
}
Ok, that will manage the selected check boxes for us.
Now, we also need to update the display (show which rows selected).
protected void GVHotels_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox chk = (CheckBox)e.Row.FindControl("chkSel");
int pkID = (int)GVHotels.DataKeys[e.Row.RowIndex]["ID"];
chk.Checked = MySelList.Contains(pkID);
}
}
Ok, we are quite much done. The user is now free to page around - select any row they want for processing. And this trick works REALLY great for some types of reports or what not. You can present grid - let user pick/choose, and then say use that result for a filter for a report, a graph, or whatever.
So, now, when the user hits that above "process" button (could be for anything).
Let's update the Hotels "Active" column = true for the ones the user selected.
Our code for the "process" button thus could be this:
protected void cmdProcess_Click(object sender, EventArgs e)
{
if (MySelList.Count >0)
{
string sWhere = " ID in (" + string.Join(",", MySelList) + ")";
string strSQL = "UPDATE tblHotels SET Active = 1 WHERE " + sWhere;
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
using (SqlCommand cmdSQL = new SqlCommand(strSQL))
{
conn.Open();
cmdSQL.ExecuteNonQuery();
}
// Clear our select list
MySelList = new List<int>();
}
}
So, the above is nice, since we don't have to update the data base for this selecting process, and OFTEN that's not our goal anyway. However, as above shows, it rather easy to apply the list to some code to update the database.
Also NOTE VERY careful that I do not show, nor display the database PK id in that GV. I don't have to, since we have the DataKeys feature for that purpose. And VERY nice is that DataKeys is 100% automatic managed server side, and the key list is NOT exposed in the client side browser as plain text. (so, MUCH better for security). And since those datakeys are not based on user input - then I was able to use a simple string concatenation for the criteria. Had I used input, or even a exposed column from the GV, then we would open up to sql injection issues - but none exist in above, since we not using any displayed column from the GV.
As noted, if you REALLY can't have a post back, then we can move this code to the final submit button, but ALSO will have code in the pager event. However, I think since post-backs occur when the user has to page around then it not all that big of a deal to have a post-back for each check box event. As noted, you can always put JUST the grid in a update panel, but even then in most cases you find the above works just fine.
On the other hand, if you really WANT the data to be updated as you move aroud? then we can dump the MySel list code, and simply bind the check box to the database row. Then on paging we can update the database. The problem then becomes what happens if the user selects some rows/check box, and DOES NOT page? In other words, we almost for sure have a final button below the grid to continue? Right? So, we can update on paging, but you have to figure out what occures if they select, and don't page? And if there is some final button to hit, then again we back to my above working example anyway.
I've dynamically created a dropdownlist within C# (No code in asp):
DropDownList myDDL = new DropDownList();
This can't be called from pageLoad() as it's not loaded everytime the page refreshes. However it's loaded everytime OnPostback(OnSelectedIndexChanged()) of another dll so I cant do !IsPostBack.
This dll is created when:
A value of another dropdownlist populates a GridView using OnSelectedIndexChanged()
<asp:DropDownList id ="select1" name="assignGetForm" runat="server" class="selectClass" AutoPostBack="True" OnSelectedIndexChanged="populateGridView">
On the GridView a function is run OnRowDatabound()(when the above OnIndexChanged() populates it) to populate myDDL inside the GridView
<asp:GridView id="GridView1" name="GridView1" onrowdatabound="populateCellsDDL" runat="server"></asp:GridView>
I'm now trying to access the values in myDDL using a button onclick() event - however this always does postback and refreshes the page so myDDL dissapears and when I print the value to console it just gives my first value select activity and not the one i've actually selected.
How would I get these values when they are changed as this dll is not populated on pageLoad().
I've tried looking at AJAX however i'm unsure how to look at the c# value through this. I tried aswell viewstates but i dont have luck as again it doesnt populate on pageLoad().
I think, you need to rebind the grid in each postback, if you want to access values of dynamically created controls.
I tried to simulate the situation with below sample code and I was able to access the value successfully.
ASPX code
<asp:DropDownList ID="select1" name="assignGetForm" runat="server" class="selectClass" AutoPostBack="True" />
<asp:GridView ID="GridView1" name="GridView1" OnRowDataBound="GridView1_DataBound" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
C# code behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
FillMainDll();
if (!IsPostBack || GridView1.Rows.Count > 0)
BindGrid();
}
private void FillMainDll()
{
select1.DataSource = new int[] { 1, 2, 3 };
select1.DataBind();
}
private void BindGrid()
{
var dt = new DataTable();
dt.Columns.Add(new DataColumn("ID", typeof(Int32)));
dt.Columns.Add(new DataColumn("Name", typeof(string)));
for (int i = 1; i < 5; i++)
{
DataRow dr = dt.NewRow();
dr[0] = i;
dr[1] = "Name - " + i.ToString();
dt.Rows.Add(dr);
}
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_DataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var myDDL = new DropDownList();
myDDL.ID = "myDDL";
myDDL.DataSource = GetGridRowDdlData();
myDDL.DataBind();
e.Row.Cells[1].Controls.Add(myDDL);
}
}
private IEnumerable<string> GetGridRowDdlData()
{
var data = new List<string>();
for (int i = 1; i < 4; i++)
{
data.Add("Name - " + i * int.Parse(select1.SelectedValue));
}
return data;
}
protected void Button1_Click(object sender, EventArgs e)
{
var sb = new System.Text.StringBuilder();
foreach (GridViewRow row in GridView1.Rows)
{
var myDDL = row.FindControl("myDDL") as DropDownList;
if (myDDL != null)
{
sb.AppendFormat("{0}<br/>", myDDL.SelectedValue);
}
}
Response.Write(sb.ToString());
}
In my project, I can add n number of textbox in gridview dynamically. My problem is, I want to fire textboxchanged event, if user change the text of any textbox in any row of gridview.
HTML CODE:
<asp:GridView ID="GridView1" runat="server"
Width="907px" style="text-align: center" CellPadding="4" ForeColor="#333333"
GridLines="None" onrowdatabound="GridView1_RowDataBound">
</asp:GridView>
ADDING COLUMNS IN GRIDVIEW:
foreach (string a in crcl)
{
SqlCommand cmd1 = new SqlCommand("select qty from purchaseinstruction where project ='" + DropDownList1.SelectedItem.ToString() + "' AND circle = '" + a + "' AND item = 'BIFURCATION' AND material = '" + mat + "'", agr);
SqlDataReader dr1 = cmd1.ExecuteReader();
if (dr1.Read())
{
string val = dr1[0].ToString();
if (val.Length > 0)
{
row[a] = val;
}
else
{
row[a] = 0;
}
}
else
{
row[a] = 0;
}
dr1.Dispose();
}
dt.Rows.Add(row);
GridView1.DataSource = dt;
GridView1.DataBind();
ADDING TEXTBOX ON ROWBOUND:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
int i = 3;
if (e.Row.RowType == DataControlRowType.DataRow)
{
crcl = (List<string>)ViewState["bdi2"];
foreach(string a in crcl)
{
TextBox TextBox101 = new TextBox();
TextBox101.ID=a;
TextBox101.Width = 60;
TextBox101.Text = (e.Row.DataItem as DataRowView).Row[a].ToString();
TextBox101.AutoPostBack = true;
e.Row.Cells[i].Controls.Add(TextBox101);
i++;
}
}
}
Here I have three problems
1. After postback textboxs get dispose
2. How to retain the value of textboxes for textboxchange?
3. How to know which textbox fire textboxchange
I've dynamically added n number of textbox in gridview and bind the data on them. I want a code behind function/method to sum textbox1, textbox2.....textboxn in textboxtotal, if user change the value in any text box. I can't add postback with these textboxes, because after postback textbox get disposed.
Code for adding Columns to Gridview dynamically
foreach (string a in crcl)
{
SqlCommand cmd1 = new SqlCommand("select qty from purchaseinstruction where project ='" + DropDownList1.SelectedItem.ToString() + "' AND circle = '" + a + "' AND item = 'BIFURCATION' AND material = '" + mat + "'", agr);
SqlDataReader dr1 = cmd1.ExecuteReader();
if (dr1.Read())
{
string val = dr1[0].ToString();
if (val.Length > 0)
{
row[a] = val;
value = value + decimal.Parse(val);
}
else
{
row[a] = 0;
}
}
else
{
row[a] = 0;
}
dr1.Dispose();
row["TOTAL"] = value;
}
dt.Rows.Add(row);
GridView1.DataSource = dt;
GridView1.DataBind();
Adding Textbox control on rowbound:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
int i = 3;
if (e.Row.RowType == DataControlRowType.DataRow)
{
crcl = (List<string>)ViewState["bdi2"];
foreach(string a in crcl)
{
TextBox TextBox101 = new TextBox();
TextBox101.ID=a;
TextBox101.Width = 60;
TextBox101.Text = (e.Row.DataItem as DataRowView).Row[a].ToString();
e.Row.Cells[i].Controls.Add(TextBox101);
i++;
}
TextBox TextBox102 = new TextBox();
TextBox102.ID = "TOTAL";
TextBox102.Width = 60;
TextBox102.Text = (e.Row.DataItem as DataRowView).Row["TOTAL"].ToString();
e.Row.Cells[i].Controls.Add(TextBox102);
}
}
Here is a little example to get you started. Add a unique class name to the TextBoxes in the GridView. Then the jQuery can bind the onblur event to them.
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" CssClass="GridTextBox"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server" CssClass="GridTextBox"></asp:TextBox>
<asp:TextBox ID="TextBox3" runat="server" CssClass="GridTextBox"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And here the javascript function that is called when the TextBox loses focus.
First the ID of the TextBox that triggers the event is split into pieces to get the ID's of the other two TextBoxes in the row (
in my case the ID looks like this ContentPlaceHolder1_GridView1_TextBox1_0).
Then it's just a matter of adding the values.
<script type="text/javascript">
$(document).ready(function () {
$('.GridTextBox').blur(function () {
var idString = this.id.split("_");
var tb1 = idString[0] + "_" + idString[1] + "_TextBox1_" + idString[3];
var tb2 = idString[0] + "_" + idString[1] + "_TextBox2_" + idString[3];
var tb3 = idString[0] + "_" + idString[1] + "_TextBox3_" + idString[3];
var total = parseInt($("#" + tb1).val()) + parseInt($("#" + tb2).val());
if (!isNaN(total)) {
$("#" + tb3).val(total);
}
});
});
</script>
You can create Javascript function in code behind, like this (if you are using WebForms):
string myScript = "function sumTextBoxes() { var arr = document.getElementsByClassName('txtBox');\n";
myScript += "var total=0;\n";
myScript += "for(var i=0;i<arr.length;i++){\n";
myScript += "if(parseInt(arr[i].value))\n";
myScript += "total += parseInt(arr[i].value);}\n";
myScript += "document.getElementById('total').value = total;}\n";
Page.ClientScript.RegisterStartupScript(this.GetType(), "myKey", myScript, true);
Now, add css class to your dynamicaly created TextBoxes (add this):
TextBox101.CssClass = "txtBox";
Also, TextBox which displays the sum should be named like this:
TextBox102.ID = "total";
Hello all I'm working on a little project where I'm adding controls to a page based on a SQL table of questions, this table will grow overtime. I just wanted to share the code and see if there was any better way or if any of the experts could chime in and give me any insight on future problems. Here is the code:
protected void Page_Load(object sender, EventArgs e)
{
try
{
SqlParameter[] paramz = new SqlParameter[1];
paramz[0] = new SqlParameter("#c_id", 1);
dt = SqlHelper.ExecuteDataTable(ConfigurationManager.ConnectionStrings["sql"].ToString(), CommandType.StoredProcedure, "get_Questions", paramz);
clinicName.Text = "<b>" + dt.Rows[0]["Clinic Name"].ToString();
for(int row = 0; row <= dt.Rows.Count; row++)
{
if (row == dt.Rows.Count) //if we're on the last question put a break for spacing(this could be fixed with styling)
{
Literal alit = new Literal();
alit.Text = "<br/>";
questionsPanel.Controls.Add(alit);
}
else
{
addQuestion(dt.Rows[row], row);
}
}
}
catch (Exception err)
{
Response.Write(err.Message);
}
}
private void addQuestion(DataRow row, int i)
{
Label lbl = new Label();
lbl.Text = row["question"].ToString();
questionsPanel.Controls.Add(lbl);
Literal lit = new Literal();
lit.Text = "<br/>";
questionsPanel.Controls.Add(lit);
TextBox txt = new TextBox();
txt.ID = "txt" + i.ToString();
questionsPanel.Controls.Add(txt);
Literal lit2 = new Literal();
lit2.Text = "<br/>";
questionsPanel.Controls.Add(lit2);
}
Use a Repeater control:
ASPX Code:
<asp:Repeater id="repData" runat="server">
<ItemTemplate>
<asp:Label id="lblQuestion" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "question") %>' />
<br />
<asp:TextBox id="lblAnswer" runat="server" />
</ItemTemplate>
<FooterTemplate>
<br />
</FooterTemplate>
</asp:Repeater>
Code behind:
// Populate repeater
SqlParameter[] paramz = new SqlParameter[1];
paramz[0] = new SqlParameter("#c_id", 1);
dt = SqlHelper.ExecuteDataTable(ConfigurationManager.ConnectionStrings["sql"].ToString(), CommandType.StoredProcedure, "get_Questions", paramz);
repData.DataSource = dt;
repData.DataBind();
If the controls either use or contribute to ViewState, then you must ensure that the same controls are added to ViewState in the same order, on every post back. The order in which objects are added to ViewState depends on the order of the controls in the control tree.