I'm building a in codebehind. The table is a listing of a database records (one record per row) and I neeed to add a delete button for each row. To do that, I of course need to build a button with a unique ID for that. To do that, I came up with the following ... which doesn't work. Any tips on how to get this working?
Button deleteButton = new Button();
deleteButton.ID = "deleteStudentWithID" + singleStudent.ID.ToString();
deleteButton.Text = "X";
string row = "<tr>";
row += "<td class=\"style5\">"+deleteButton.ClientID +"</td>";
row += "</tr>";
Your problem is that you're adding only the ClientID of your control to the html and not adding the control to the page itself.
Controls.Add(new LiteralControl("<table>"));
foreach(var singleStudent in students)
{
Controls.Add(new LiteralControl("<tr>"));
//Code to add other columns
Button deleteButton = new Button();
deleteButton.ID = "deleteStudentWithID" + singleStudent.ID.ToString();
deleteButton.Text = "X";
Controls.Add(new LiteralControl("<td class=\"style5\">"));
Controls.Add(deleteButton);
Controls.Add(new LiteralControl("</td></tr>");
}
Controls.Add(new LiteralControl("</table>"));
Instead of creating the entire table markup in your code behind, use the controls made available by ASP.NET.
For an example, place this in your .aspx:
<table>
<asp:Repeater runat="server" ID="MyRepeater1">
<ItemTemplate>
<tr>
<td><%# Eval("StudentName")%></td>
<td>... other student object bindings ...</td>
<td>
<asp:Button runat="server" ID="MyDeleteButton"
CommandArgument='<%# Eval("ID")%>'
CommandName="Delete"
OnCommand="MyDeleteButton_Command"
Text="X" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
And include this in your code-behind:
protected void Page_Load(object sender, EventArgs e)
{
MyRepeater1.DataSource = new MyStudent[]
{
new MyStudent()
{
ID = 1,
StudentName = "Student 1"
},
new MyStudent()
{
ID = 2,
StudentName = "Student 2"
}
};
MyRepeater1.DataBind();
}
protected void MyDeleteButton_Command(object sender, CommandEventArgs e)
{
switch (e.CommandName)
{
case "Delete":
// stuff for deleting by e.CommandArgument
break;
}
}
The best Solution to Your problem i can think of is
Button deleteButton = new Button();
deleteButton.ID = "deleteStudentWithID" + singleStudent.ID.ToString();
deleteButton.Text = "X";
StringBuilder sb = new StringBuilder();
StringWriter writer = new StringWriter(sb);
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
deletedButton.RenderControl(htmlWriter);
string row = "<tr>";
row += "<td class=\"style5\">"+sb.toString(); +"</td>";
row += "</tr>";
This way you can get any control's HTML. :) If you are building dynamically HTML from code behind then try not to use string rather StringBuilder. strings are immutable and has performance penalty.
Related
In my aspx file I have the following code:
<asp:PlaceHolder ID="phdHolding" runat="server">
<asp:Label ID="lblWarning" runat="server" Text="" Visible="false" />
<asp:PlaceHolder ID="phdInput" runat="server" Visible="false">
<h3><asp:Label ID="lblArea" runat="server" Text="Area" /></h3>
</asp:PlaceHolder>
</asp:PlaceHolder>
In code behind (c#) I create a table which is added to phdInput. One part of that code is the creation and population of a TextBox (and Label) within a Table Cell. The TextBox is required to call a function on TextChanged.
decimal amount = Convert.ToDecimal(dc.DataScalar("SELECT Item" + rownr + " FROM Companies WHERE CompanyName='" + coy + "' AND BusinessUnit='" + bu + "'"));
TextBox tb = new TextBox(); tb.ID = "txtAmount" + rownr; tb.Width = 70; tb.Text = amount.ToString("N0");
tb.AutoPostBack = true; tb.TextChanged += new EventHandler(UpdateAmounts);
Label lbl = new Label(); lbl.Text= " " + trow["Unit"].ToString();
TableCell tdamount = new TableCell(); tdamount.Controls.Add(tb); tdamount.Controls.Add(lbl);
tr2.Cells.Add(tdamount);
This is all working fine and everything is displayed on the page. However, when the text is changed and you click outside the textbox or press'Enter' etc. the function is not being reached (have checked in VS) and phdInput becomes blank.
I have used this function, and the TextChanged method of calling it, before with no issues so why is it not working now?
I have managed to recreate one problem
phdInput becomes blank
This was suspicious, if it disappears there must be PostBack in the action. Suspicion rises especially because phdInput attribute Visible is set to false on the form.
I suppose form's initialization is happening inside the Page_Load method and one of the code behind lines is to set phdInput attribute Visible to true. However, phdInput disappears after PostBack is fired, so there's probably check
if (!IsPostBack)
Initialization is happening inside of it, which is correct, no need to initialize it every time page reloads. However
phdInput.Visible = true;
should be outside of check if (!IsPostBack) in order to phdInput be always visible.
Next, something fires the PostBack.
However, when the text is changed and you click outside the textbox or
press'Enter' etc. the function is not being reached (have checked in
VS) and phdInput becomes blank.
This sounds like TextChanged event works, it only calls some other event handler.
I hope it will help you find the solution. Here follows the code that recreates the issue phdInput becomes blank (it is poorly written).
.aspx - content of body tag
<form id="form1" runat="server">
<div>
<p>start</p>
<asp:PlaceHolder ID="phdHolding" runat="server">
<asp:Label ID="lblWarning" runat="server" Text="" Visible="false" />
<asp:PlaceHolder ID="phdInput" runat="server" Visible="false" >
<h3><asp:Label ID="lblArea" runat="server" Text="Area" /></h3>
</asp:PlaceHolder>
</asp:PlaceHolder>
<p>end</p>
</div>
</form>
code behind
using System;
using System.Web.UI.WebControls;
namespace WebApplication8
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
// row 1
int rownr = Convert.ToInt32(1);
TableRow tr = new TableRow();
tr.VerticalAlign = VerticalAlign.Top;
TableCell tdtype = new TableCell();
tdtype.Text = "table cell 1 text";
tdtype.Width = 250;
tdtype.HorizontalAlign = HorizontalAlign.Left;
tr.Cells.Add(tdtype);
decimal amount = Convert.ToDecimal(1);
TextBox tb = new TextBox(); tb.ID = "txtAmount" + rownr; tb.Width = 70; tb.Text = amount.ToString("N0");
tb.AutoPostBack = true; tb.TextChanged += new EventHandler(UpdateAmounts);
Label lbl = new Label(); lbl.Text = " " + "1";
TableCell tdamount = new TableCell(); tdamount.Controls.Add(tb); tdamount.Controls.Add(lbl);
tr.Cells.Add(tdamount);
// row 2
int rownr2 = Convert.ToInt32(2);
TableRow tr2 = new TableRow();
tr2.VerticalAlign = VerticalAlign.Top;
TableCell tdtype2 = new TableCell();
tdtype2.Text = "table cell 2 text";
tdtype2.Width = 250;
tdtype2.HorizontalAlign = HorizontalAlign.Left;
tr2.Cells.Add(tdtype2);
decimal amount2 = Convert.ToDecimal(2);
TextBox tb2 = new TextBox(); tb2.ID = "txtAmount" + rownr2; tb2.Width = 70; tb2.Text = amount2.ToString("N0");
tb2.AutoPostBack = true; tb2.TextChanged += new EventHandler(UpdateAmounts);
Label lbl2 = new Label(); lbl2.Text = " " + "2";
TableCell tdamount2 = new TableCell(); tdamount2.Controls.Add(tb2); tdamount2.Controls.Add(lbl2);
tr2.Cells.Add(tdamount2);
// table
var table = new Table();
table.Rows.Add(tr);
table.Rows.Add(tr2);
phdInput.Controls.Add(table);
lblWarning.Text = "some warning";
lblArea.Text = "some area text";
lblWarning.Visible = true;
phdInput.Visible = true;
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
protected void UpdateAmounts(object sender, EventArgs e)
{
}
}
}
when page is opened
after textbox's text is changed - either one
I'm having a problem to get controls/ controls id that I have created manually from code behind. after doing research I found if I create the table and its all component including any controls in Page_Init() method, when rendering after postback the text value of textbox control should be available to the page. i tried to locate the textbox control using FindControl() method. when debugging it only reach to the line where I tried to locate the control using FindControl() and then throw an exception "Object reference not set to an instance of an object" bellow is the Page_Init() method
protected void Page_Init(object sender, EventArgs e)
{
Table tb = new Table();
tb.ID = "Table1";
TableRow row1 = new TableRow();
TableCell cell1 = new TableCell();
TableCell cell2 = new TableCell();
TableCell cell3 = new TableCell();
TextBox txtbx = new TextBox();
Button btn = new Button();
cell1.Text = "Name: ";
txtbx.ID = "table1_text_input";
txtbx.ValidationGroup = "rosy";
cell2.Controls.Add(txtbx);
btn.Text = "Get the input";
btn.ValidationGroup = "rosy";
btn.Click += getBoxinput_Click;
cell3.Controls.Add(btn);
// adding cells to row1
row1.Cells.Add(cell1);
row1.Cells.Add(cell2);
row1.Cells.Add(cell3);
// adding row to table1
tb.Rows.Add(row1);
Panel1.Controls.Add(tb);
}
below is the button click event that supposes to display the control id and its text. I'm stuck with this for the last couple of days. any help will be appreciated.
protected void getBoxinput_Click(object sender, EventArgs e)
{
try
{
if (IsPostBack)
{
Table t = (Table)Page.FindControl("Panel1").FindControl("Table1");
TextBox tbox;
foreach (TableRow tr in t.Rows)
{
foreach (TableCell tc in tr.Cells)
{
foreach (Control cnt in tc.Controls)
{
if (cnt.GetType() == typeof(TextBox))
{
tbox = (TextBox)cnt;
display.Text += "control id: " + tbox.ID + " control input: " + tbox.Text + "<br/>";
}
}
}
}
}
}
catch (NullReferenceException ex)
{
display.Text += ex.Message;
}
}
Maybe I am missing something but why don't you just put all the controls in the global scope of the class (instead of just creating the instances inside Page_Init) so that you can access them in any part of your class. Of course I am assuming that Page_Init and getBoxinput_Click are in the same class.
EDIT:
Here is the example on how to put the variables in the global scope:
Table tb; //Declare variables outside any function.
protected void getBoxinput_Click(object sender, EventArgs e)
{
tb = new Table(); //Initialize them inside a function.
}
This way you will be able to access tb inside any function.
Your code is working perfectly. Here is what I used for the form markup:
<form id="form1" runat="server">
<asp:Panel ID="Panel1" runat="server"></asp:Panel>
<asp:Label ID="display" runat="server"></asp:Label>
</form>
I want to create link buttons dynamically and link them to the anchors in a repeater.
Here is what I tried:
int listItemIds = 1;
List<CompanyModel1> companies1 = new List<CompanyModel1>();
for (int ar = 0; ar < arrProcess.Length; ar++)
{
LinkButton lnk = new LinkButton();
lnk.ID = "lnk" + listItemIds;
lnk.Text = arrProcess[ar];
lnk.Attributes.Add("onClick", "return false;"); //This is to prevent the page to reload
lnk.Click += new System.EventHandler(this.colorClick);
lnk.CommandArgument = Convert.ToString(ar); //LinkButton CommandArgument
lnk.CommandName = Convert.ToString(ar); //LinkButton CommanName
lnk.Command += new CommandEventHandler(lb_Command);//
listItemIds++;
PlaceHolder1.Controls.Add(lnk); // Adding the LinkButton in PlaceHolder
and
protected void colorClick(object o, EventArgs e)
{
LinkButton lnk = (LinkButton)o;
lnk.Style["font-weight"] = "bold";
//Process clicked link. for example jump to anchors
}
In my aspx file, I created the place holder to populate the link button to:
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</div>
I want to prevent the page from reload so that the result I binded to the repeater is still there. But I do not see the button links to change. I want to make it change in color and font style so that we know that it is clicked. More over I want it to jump to the anchors when clicked. But I don't know how to create that anchors. Do you have any idea on that ? Thank you!
You must use the OnClientClick event.
And the server to get it.
lnk.Attributes.Add("OnClientClick","window.open('Command.aspx','width=400,Height=400,top=200,left=200'); return false;");
This example opens a link. You can change its color.
Update 1:To call with out reload page use this.
jquery code:
$.ajax({
type: "POST",
url: "_Default.aspx/GetDate",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// Do something interesting here.
}
});
asp.net code :
public partial class _Default : Page
{
[WebMethod]
public static string GetDate()
{
return DateTime.Now.ToString();
}
}
If you remove below line from your code it should work.
lnk.Attributes.Add("onClick", "return false;");
If your page load have IsPostBack check that also need to remove.
Working Code:
protected void Page_Load(object sender, EventArgs e)
{
string[] arrProcess = new[] { "link 1", "link 2", "link 3" };
int listItemIds = 1;
// List<CompanyModel1> companies1 = new List<CompanyModel1>();
for (int ar = 0; ar < arrProcess.Length; ar++)
{
LinkButton lnk = new LinkButton();
lnk.ID = "lnk" + listItemIds;
lnk.Text = arrProcess[ar];
//lnk.Attributes.Add("onClick", "var btn = document.getElementById('"+lnk.ID+"');btn.innerHTML = 'Default Text';btn.innerHTML.style.fontWeight = 'bold';return false;"); //This is to prevent the page to reload
lnk.Click += new System.EventHandler(this.colorClick);
lnk.CommandArgument = Convert.ToString(ar); //LinkButton CommandArgument
lnk.CommandName = Convert.ToString(ar); //LinkButton CommanName
//lnk.Command += new CommandEventHandler(lnk_Command);
listItemIds++;
PlaceHolder1.Controls.Add(lnk); // Adding the LinkButton in PlaceHolder
PlaceHolder1.Controls.Add(new LiteralControl("<br />"));
}
}
protected void colorClick(object o, EventArgs e)
{
LinkButton lnk = (LinkButton)o;
lnk.Style["font-weight"] = "bold";
//Process clicked link. for example jump to anchors
}
Update:
You can stop full page post back using update panel like below. This will still call the page load but its partial call back.
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</div>
</ContentTemplate>
</asp:UpdatePanel>
Also master page you need to add a script manager.
OK. I got what you want now. do the following steps.
We have to change your back end. I have use Hyper Link rather than Link button.
protected void Page_Load(object sender, EventArgs e)
{
string[] arrProcess = new[] { "link 1", "link 2", "link 3" };
int listItemIds = 1;
// List<CompanyModel1> companies1 = new List<CompanyModel1>();
for (int ar = 0; ar < arrProcess.Length; ar++)
{
HyperLink lnk = new HyperLink();
lnk.ID = "lnk" + listItemIds;
lnk.ClientIDMode = ClientIDMode.Static;
lnk.NavigateUrl = "#";
lnk.Text = arrProcess[ar];
lnk.Attributes.Add("onClick", "changeControlStyle('" + lnk.ClientID + "');"); //This is to prevent the page to reload
listItemIds++;
PlaceHolder1.Controls.Add(lnk); // Adding the LinkButton in PlaceHolder
//PlaceHolder1.Controls.Add(new LiteralControl("<br />"));
}
}
Then I have add a javascript method to page. that will use in the code behind.
<script type="text/javascript">
function changeControlStyle(id) {
document.getElementById(id).style.fontWeight = "bold";
}
</script>
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</div>
Aspx page:
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<asp:placeholder id="container" runat="server" visible="false"></asp:placeholder>
</td>
</tr>
</table>
On Code Behind file:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
generateDynamicControls();
}
private void generateDynamicControls()
{
for (int i = 0; i < dt.Rows.Count; i++)
{
HtmlGenericControl tr = new HtmlGenericControl("tr");
HtmlGenericControl td1 = new HtmlGenericControl("td");
Label lbl = new Label();
lbl.ID = "lbl" + dt.Rows[i]["sSubjectName"].ToString();
lbl.Text = dt.Rows[i]["sSubjectName"].ToString() + " :";
lbl.Width = new Unit(170);
lbl.Style.Add("padding-left", "10px");
lbl.Style.Add("font-weight", "bold");
td1.Controls.Add(lbl);
tr.Controls.Add(td1);
HtmlGenericControl td2 = new HtmlGenericControl("td");
TextBox txtBox = new TextBox();
txtBox.ID = "txt" + dt.Rows[i]["sSubjectName"].ToString();
txtBox.CssClass = "TxtBox";
txtBox.TextMode = TextBoxMode.MultiLine;
txtBox.Width = new Unit(840);
td2.Style.Add("colspan", "3");
td2.Controls.Add(txtBox);
tr.Controls.Add(td2);
container.Controls.Add(tr);
HtmlGenericControl tr1 = new HtmlGenericControl("tr");
HtmlGenericControl td3 = new HtmlGenericControl("td");
td3.Style.Add("colspan", "4");
td3.InnerHtml = " ";
tr1.Controls.Add(td3);
container.Controls.Add(tr1);
//container.Controls.Add(new LiteralControl("<br />"));
//LiteralControl literalBreak = new LiteralControl();
//literalBreak.Text ="</br>";
}
container.Visible = true;
}
}
`dt(datatable)` is filled from other function.
this is working fine and controls are created correclty.
But I want to recreate this dynamic controls on selected change event of dropdownlist. but before recreate these controls i have to delete previously created controls.
I have tried below code in dropdownlist selected changed event to delete these controls and recreate new controls.
for (int i = 0; i < dt.Rows.Count; i++)
{
container.Controls.Remove(container.FindControl(dt.Rows[i]["nSubjectId"].ToString()));
}
generateDynamicControls();
But it's not work and give me following error. becuase of onload event is alread ycalled first and created the dyanmic controls.
Multiple controls with the same ID 'lblOrals' were found. FindControl requires that controls have unique IDs.
How can I solve this problem.
Please help me solve this problem.
Thanks in advance
Try this
Give the for loop variable (i) to your label id, like the below way
lbl.ID = "lbl" + dt.Rows[i]["sSubjectName"].ToString()
+i.ToString();//i is loop variable for coordinated with labelid.
Now if the "dt.Rows[i]["sSubjectName"]" is return "LabeleName", When the for loop will assign the values like
dt.Rows[i]["sSubjectName"].ToString() + i.ToString() , So It is return values like "LabeleName1"
Finally you got the label id's are followings name
lblLabeleName1
lblLabeleName2
lblLabeleName3
.
.
.
.etc
textbox are like
txtBox.ID = "txt" + dt.Rows[i]["sSubjectName"].ToString() + i.ToString();
Result are
txtLabeleName1
txtLabeleName2
txtLabeleName3
.
.
.
etc.
Remove fields code like
//For label
container.Controls.Remove(container.FindControl("lbl" + dt.Rows[i]["sSubjectName"].ToString() +i.ToString()));
//For TextBox
container.Controls.Remove("txt" + dt.Rows[i]["sSubjectName"].ToString()+ i.ToString() ));
And Should call the generateDynamicControls(); method inside of !ISPostBack() event in page load event
Like
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if(!IsPostBack)
{
generateDynamicControls();
}
}
I am dynamically creating a table with data and check boxes in it, my problem is when i check to see one specific check-box is checked, out of many, it resets to the default state of false (note: its not just one it doesn't work with, it works with non of the generated check boxes)
Before i create the page_load function i create the check box, further down i create the table, and populate it with data, then i set up a function to check on a click to see if the box was indeed checked, iv'e tried many iterations of this with no luck
protected void table_builder(SqlDataReader readerinfo)
{
//Create a new step for the user
step3label.Text = "3.";
//Table header
TableHeaderRow hr = new TableHeaderRow();
TableHeaderCell hc = new TableHeaderCell();
TableHeaderCell hc2 = new TableHeaderCell();
TableHeaderCell hc3 = new TableHeaderCell();
hr.Cells.Add(hc);
hc.Text = "ID"; //Assign header 1 with a name
hr.Cells.Add(hc2);
hc2.Text = "Name";//Assign header 2 with a name
hr.Cells.Add(hc3);
hc3.Text = "Selection";
Table1.Rows.Add(hr);
//Dynamic Table Generation
int numcells = 3;
int triswitch = 0;//this is use to chose which cell is made, id, name or selection
string checkboxID = null;
while (readerinfo.Read()) //execute the following aslong as there is data to fill the table with
{
for (int j = 0; j < 1; j++)
{
TableRow r = new TableRow();
for (int i = 0; i < numcells; i++)
{
TableCell c = new TableCell();
switch (triswitch)
{
case 0: // this case sets the info for the feild id
c.Text = readerinfo.GetSqlGuid(0).ToString();
checkboxID = readerinfo.GetSqlGuid(0).ToString();
r.Cells.Add(c);
triswitch = 1;
break;
case 1:
c.Text = readerinfo.GetString(1);
r.Cells.Add(c);
triswitch = 2;
break;
case 2:
Checkbox_creator(checkboxID,ref c);
r.Cells.Add(c);
triswitch = 0;
break;
}
}
Table1.Rows.Add(r);
}
}
}
protected void Checkbox_creator(string id,ref TableCell send)
{
//create the checbox
ckbx = new CheckBox();
ckbx.ID = "CBX" + checkboxid.ToString();
checkboxid++;
ckbx.InputAttributes.Add("value", id);
send.Controls.Add(ckbx); //add the chekbox to the cell
checkboxidlist.Add(id);//add the id of the checkbox to the list
}
//
//AFTER DATATABLE IS LOADED
//
public void test()
{
// Find control on page.
CheckBox myControl1 = (CheckBox)Table1.FindControl("CBX0");
if (myControl1 != null)
{
// Get control's parent.
Control myControl2 = myControl1.Parent.Parent.Parent;
Response.Write("Parent of the text box is : " + myControl2.ID);
if (myControl1.Checked == true)
{
Response.Write("check box checked");
}
}
else
{
Response.Write("Control not found");
}
}
//on Submit button click, execute the following function
protected void Submit_Click(object sender, EventArgs e)
{
//Code to be executed
string Userinput; //declare Userinput variable
Userinput = Searchbox.Value; // Set variable to asp controll
Response.Write("<br /> <br />"+ Userinput +" <- user imput works");
ConnectToSql(Userinput);//insert what the user submitted into a query
test();
//
//
//NoTe code validation is needed to prevent injections
//
}
So basically what is happening here is that you are dynamically dropping this onto the page every time the page loads. Because you are doing this dynamically, the checkbox that fires off a "checked" event or is checked against during a postback no longer exists as it is not part of the viewstate. The way that the ASP.NET page lifecycle works is to fire off the sequence of lifecycle events regardless of whether or not the page is posted back or not, meaning that a new page is built upon you firing a postback event and the page goes through preinit, init, preload, load, and all that jazz before it actually hits any of the event handling code. The page that exists for the postback has a freshly created set of checkboxes that have no binding to the ones that were on the previous page.
You have a few options here, and here are two of them:
Have the 'checked' event fire a postback and have the unique ID of the web control checked against a collection you maintain on the server. You can drop the controls onto the page via a repeater or gridview and hook into its populate event. In doing so you can add the unique ID of the control that was just added into a Dictionary that you store in session that maintains any relationship that you want from a checkbox to a piece of data.
Use Javascript to update a hidden field that is always on the page and has view state enabled. In doing so you can have some sort of delimited string containing the information you deem relevant to the 'checked' checkboxes. Every time a checkbox is checked, add its identifying information to the hidden input field's value and then when the postback fires you should be able to check that hidden input for its value and do whatever you need to do from there.
These both seem like pretty hairy ways of handling this though. If you elaborate on what exactly you need then perhaps I can give you a better suggestion.
add the check boxes to the page before the view state is loaded and the event fires. Do it in the OnInit method not the onload. Use Onload to see if they're checked or not. Be sure you're giving them ID's. Unless this is a partial postback (ajax) then only render the check boxes if !IsPostback
It appears after two days of searching, i have found a pretty good solution that is much quicker and easier to understand than some others; It appears that as the other answers state, it is because of the page_load, however in this situation init is not needed, you simply need to recreate all of the controls before you can do anything else.
The key to this solution is:
protected void RecreatePreviousState()
{
if (this.IsPostBack)
{
//code to recreate
}
}
Where the comment in the above code is, is where you call the main function that creates all of your controls, like in my example it was:
ConnectToSql(Searchbox.Value)
below will be all of the code associated with this page, for future reference for anyone with this problem.
Code Behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;
public partial class codebehind : System.Web.UI.Page
{
//DECLARATIONS
string selectedvalue;
List<string> createdckbxs = new List<string>();
List<string> CheckedCheckboxes = new List<string>();
CheckBox ckbx;
int ckbxID = 0;
//END DECLARATIONS
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(DateTime.Now); //local time -- testing
Response.Write("<br /><br />NOTE: the id feild in the below table will be useless soon, it is only for testing purposes, look at CRM<br /><br />");
selectedvalue = Request.QueryString["filter"];
//88888888888888888
RecreatePreviousState();
//88888888888888888
Response.Write(selectedvalue);
instructionsfunc();
}
protected void instructionsfunc()
{
switch (selectedvalue)
{
case "Name":
instructions.Text = "Please enter the first few letters of the company you are looking for, ex. for "some company", you might search som";
break;
case "State":
instructions.Text = "Please enter the abreviation of the state you are looking for, ex. for New York, enter NY";
break;
}
}
protected string sqlSelector(string uinput)
{
switch (selectedvalue) //create the sql statments
{
case "Name":
return "SELECT [id],[name] FROM [asd].[jkl] WHERE [name] LIKE '" + uinput + "%' and [deleted] = 0 ORDER BY [name] ASC";
case "State":
return "SELECT [id],[name] FROM [asd].[jkl] WHERE [shipping_address_state] LIKE '" + uinput + "%' and [deleted] = 0 ORDER BY [name] ASC";
default:
Response.Redirect("errorpage.aspx?id=002");
return null;
}
}
//on Submit button click, execute the following function NOTE THIS BUTTON's ONLY USE IS POSTBACK
protected void Submit_Click(object sender, EventArgs e)
{
string Userinput; //declare Userinput variable
Userinput = Searchbox.Value; // Set variable to asp controll
Response.Write("<br /> <br />"+ Userinput +" <- user imput works");
}
//on Clear button click execute the following function
protected void Clear_Click(object sender, EventArgs e)
{
Response.Redirect(Request.RawUrl);
}
protected void ConnectToSql(string input)
{
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
//Todo add any aditional data needed to connection
conn.ConnectionString = ConfigurationManager.ConnectionStrings["SplendidTestConnectionString"].ConnectionString;
try
{
conn.Open();
//this is the actual sql, this gets the data
SqlCommand sqlString2 = new SqlCommand();
sqlString2.CommandText = sqlSelector(input);
sqlString2.CommandTimeout = 15;
sqlString2.CommandType = System.Data.CommandType.Text;
sqlString2.Connection = conn;
SqlDataReader reader;
reader = sqlString2.ExecuteReader();
table_builder(reader);
reader.Close(); //close the sql data reader
}
catch (Exception e)
{
//Some sort of redirect should go here to prevent the user from vewing a broken page
conn.Close();
//Response.Redirect("errorpage.aspx?id=001");
Response.Write(e);
}
finally
{
if (conn.State != System.Data.ConnectionState.Closed)
{
conn.Close();//close up the connection after all data is done being populated
}
}
}
protected void table_builder(SqlDataReader readerinfo)
{
//Create a new step for the user
step3label.Text = "3.";
//Table header
TableHeaderRow hr = new TableHeaderRow();
TableHeaderCell hc = new TableHeaderCell();
TableHeaderCell hc2 = new TableHeaderCell();
TableHeaderCell hc3 = new TableHeaderCell();
hr.Cells.Add(hc);
hc.Text = "ID"; //Assign header 1 with a name
hr.Cells.Add(hc2);
hc2.Text = "Name";//Assign header 2 with a name
hr.Cells.Add(hc3);
hc3.Text = "Selection";
Table1.Rows.Add(hr);
//Dynamic Table Generation
int numcells = 3;
int triswitch = 0;//this is use to chose which cell is made, id, name or selection
while (readerinfo.Read()) //execute the following aslong as there is data to fill the table with
{
for (int j = 0; j < 1; j++)
{
TableRow r = new TableRow();
for (int i = 0; i < numcells; i++)
{
TableCell c = new TableCell();
switch (triswitch)
{
case 0: // this case sets the info for the feild id
c.Text = readerinfo.GetSqlGuid(0).ToString();
//RENAME THIS To ADDING BUTTON = readerinfo.GetSqlGuid(0).ToString();
r.Cells.Add(c);
triswitch = 1;
break;
case 1:
c.Text = readerinfo.GetString(1);
r.Cells.Add(c);
triswitch = 2;
break;
case 2:
ckbx = new CheckBox();
ckbx.ID = "CBX" + ckbxID;
createdckbxs.Add(ckbx.ID);
c.Controls.Add(ckbx);
r.Cells.Add(c);
triswitch = 0;
ckbxID++;
break;
}
}
Table1.Rows.Add(r);
}
}
}
//
//AFTER DATATABLE IS LOADED
//
protected void RecreatePreviousState()
{
if (this.IsPostBack)
{
ConnectToSql(Searchbox.Value);
MergeBtnCreate();
}
}
protected void MergeBtnCreate()
{
Button MergeBTN = new Button();
MergeBTN.Text = "Merge";
MergeBTN.Click += new EventHandler(MergeBTN_Click);
MergeBTNHolder.Controls.Add(MergeBTN);
}
void MergeBTN_Click(object sender, EventArgs e)
{
foreach(string id in createdckbxs)
{
CheckBox myControl1 = (CheckBox)Table1.FindControl(id);
if (myControl1 != null)
{
if (myControl1.Checked == true)
{
CheckedCheckboxes.Add(id);
}
}
else
{
Response.Redirect("errorpage.aspx?id=003");
}
}
}
}
Asp.net
<%# Page Language="C#" AutoEventWireup="true" CodeFile="codebehind.aspx.cs" Inherits="codebehind" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Hello</title>
</head>
<body>
<form id="form1" runat="server">
<div style="background-color:#55aaff;margin-bottom:10px;padding:5px;">
<h3 style="padding:2px;margin:0px;">
2.
</h3>
<asp:Label ID="instructions" runat="server" />
<asp:Label ID="buttonclicked" runat="server" />
<br />
<input id="Searchbox" type="text" runat="server" />
<br />
<asp:Button ID="SubmitBTN" runat="server" OnClick="Submit_Click" Text="Submit" />
<asp:Button ID="ClearBTN" runat="server" OnClick="Clear_Click" Text="Clear" />
</div>
<div>
<h3 style="padding:2px;margin:0px;">
<asp:Label ID="step3label" runat="server" Text=""></asp:Label>
</h3>
<asp:Table ID="Table1" runat="server" GridLines="Both" />
</div>
<div>
<asp:PlaceHolder ID="MergeBTNHolder" runat="server"></asp:PlaceHolder>
</div>
</form>
</body>
</html>