i have a page where i create 2 checkboxes dynamically.
TableRow tr = new TableRow();
for (int i = 0; i < 2; i++)
{
TableCell Tc = new TableCell();
Tc.Attributes["style"] = "line-height: 30px; text-align: left";
Tc.Attributes["width"] = "50%";
Tc.Style.Add("padding-left", "5px");
//Checkboxes on left along with labels
CheckBox checkBoxCtrl = new CheckBox();
checkBoxCtrl.ID = "checkBoxCtrl" + i;
Tc.Controls.Add(checkBoxCtrl);
tr.Cells.Add(Tc);
}
once they are created in the page load event i have a Ok_button click event which requires to check if the checkbox is checked or not.
protected void Update2_Click(object sender, EventArgs e)
{
if(checkBoxCtrl.checked)
//here i wont be able to get the value
// i get the error the name checkBoxCtrl does not exist..
{
response.write("true");
}
}
but how do i do the check in this case.
thanks
Answer:
this is what needs to be done to get the checkbox values
protected void Update1_Click(object sender, EventArgs e)
{
for(int i = 0; i < ControlPropList.Count; i++)
{
CheckBox chkTest = (CheckBox)xxx.FindControl("checkBoxCtrl" + i);
{
if (chkTest.Checked)
{
Global.logger.Info("Checkbox True = " + chkTest.ID);
}
else
{
Global.logger.Info("Checkbox False = " + chkTest.ID);
}
}
}
}
This should work fine as long as you add the checkboxes to your page in the Page_PreInit method. If you add them after that (Page_Load for example), their values will not be maintained.
Read about the asp.net page lifecycle here:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Consider storing the dynamic checkbox in a local member:
private CheckBox _myCustomCheckbox = new CheckBox();
protected override void OnInit(EventArgs e)
{
TableRow tr = new TableRow();
for (int i = 0; i < 2; i++)
{
TableCell Tc = new TableCell();
if (i == 0)
{
Tc.Attributes["style"] = "line-height: 30px; text-align: left";
Tc.Attributes["width"] = "50%";
Tc.Style.Add("padding-left", "5px");
//Checkboxes on left along with labels
_myCustomCheckbox.ID = "checkBoxCtrl" + j;
Tc.Controls.Add(_myCustomCheckbox);
tr.Cells.Add(Tc);
}
}
// the row needs added to a page control so that the child control states can be loaded
SomeTableOnThePage.Controls.Add(tr);
base.OnInit(e);
}
protected void Update2_Click(object sender, EventArgs e)
{
if(_myCustomCheckbox.Checked)
{
response.write("true");
}
}
May not be quite what you want, but I had a similar issue, I have a dynamically generated table in ASP.NET page, with dynamically generated CheckBoxes in one column. I have created the data for the table from a collection, and then as the dynamic CB's are created I give them an ID and store them in a second collection, such as an array of CB's.
So when I need to find the Checked value I simply iterate through the collection, and I can find the ones that are Checked.
Also as they were created simultaneously with the data in the dynamic table I was able to easily tie the table data row to the Checkbox value.
This obviously assumes that the dynamic table and CB's were created using some kind of looping.
This may not be the best solution but works for my current needs.
Related
In my asp.net application, I have used Gridview control, In which i have to add Dropdownlist at runtime for each cell.Which i am able to bind successfully.
Below is my code which inside row databound event,
foreach (GridViewRow row in gdvLocation.Rows) {
if (row.RowType == DataControlRowType.DataRow) {
for (int i = 1; i < row.Cells.Count; i++) {
var dlRouteType = new DropDownList();
dlRouteType.ID = "ddlRouteType";
dlRouteType.DataSource = GetRouteTypeList();
dlRouteType.DataTextField = "RouteType";
dlRouteType.DataValueField = "Id";
dlRouteType.DataBind();
row.Cells[i].Controls.Add(dlRouteType);
}
}
}
I have a button in my page, which has functionality to save data to database . While saving data i have to pass the value from Dropdownlist which i have added at runtime. On button click i am writing following code to get data from dropdownlist,
var ddlDropDown = (DropDownList)row.Cells[i].FindControl("ddlRouteType");
But i am getting null in ddlDropDown object. I have even added Update panel inside aspx page. Any suggessions most welcome.
Thanks in advance
Sangeetha
You have these errors in your code
RowDataBound already iterates through each rows and so all you need not write that foreach on top
You are iterating from index 1, index are zero-based. So start from zero.
The DropDownList ID must be unique, so better write something like,dlRouteType.ID = "ddlRouteType_" + i;
The code should be,
protected void gdvLocation_RowDataBound(object sender, GridViewRowEventArgs e)
{
//removed the foreach loop
var row = e.Row;
if (row.RowType == DataControlRowType.DataRow)
{
for (int i = 0; i < row.Cells.Count; i++) //changed index
{
var dlRouteType = new DropDownList();
dlRouteType.ID = "ddlRouteType_" + i; //gave unique id
dlRouteType.DataSource = GetRouteTypeList();
dlRouteType.DataTextField = "RouteType";
dlRouteType.DataValueField = "Id";
dlRouteType.DataBind();
row.Cells[i].Controls.Add(dlRouteType);
}
}
}
ASP.NET C#.
Inside UpdatePanel we have TextBox with OnTextChanged="text_changed" method and Panel.
if number 3 was typed at textbox, 3 textboxes below will appear inside Panel with different IDs.
However when button outside updatepanel clicks, dynamically created textboxes not found error occured.
How to get values of dynamically created textboxes?
Creating textbox:
protected void text_changed(Object sender, EventArgs e)
{
int n = Int32.Parse(TextBox6.Text);
Table table = new Table();
for (int i = 0; i < n; i++)
{
TableRow trow = new TableRow();
table.Rows.Add(trow);
TableCell tcell = new TableCell();
tcell.Text = (i + 1).ToString();
TextBox tb = new TextBox();
tb.ID = "TB" + i.ToString();
tcell.Controls.Add(tb);
trow.Cells.Add(tcell);
}
Panel1.Controls.Add(table);
ButtonClick //get values from created textboxes:
int n = Int32.Parse(TextBox6.Text);
for (int i = 0; i < n; i++)
{
string title = ((TextBox)UpdatePanel1.FindControl("Panel1").FindControl("TB" + i.ToString())).Text; //here null pointer exception..
}
where are you generating your textboxes? if you're creating them in text_changed event, then on the next post back your going to run into pagelife cycle issues. you'd need to cache the fact that you created them, and recreate them in the OnInit phase of the page.
I am creating a few checkboxes when I open a form with the following code:
private void OpenFolder_Load(object sender, EventArgs e)
{
int i = 0;
foreach (string file in filesToOpen)
{
Label lbl = new Label();
lbl.Text = Path.GetFileNameWithoutExtension(file);
lbl.Width = 200;
lbl.Height = 25;
lbl.AutoEllipsis = true;
lbl.Location = new System.Drawing.Point(10, 40 + 25 * i);
this.Controls.Add(lbl);
string checkName = "check" + i;
CheckBox check = new CheckBox();
check.Checked = true;
check.AccessibleName = checkName;
check.Location = new System.Drawing.Point(340, 40 + 25 * i);
check.CheckedChanged +=new EventHandler(check_CheckedChanged);
this.Controls.Add(check);
CheckBoxes.Add(check);
i++;
}
and I am trying to check the state of the checkboxes everytime one changes to toggle my OK button (the user can validate only if there are a certain number of the checkboxes checked)
here is the code I use, but it fails as I am not able to target the checkboxes:
private void check_CheckedChanged(Object sender, EventArgs e)
{
for (int i = 0; i < filesToOpen.Count(); i++)
{
string tbarName = "tbar" + i;
string checkName = "check" + i;
CheckBox ckb = this.Controls.OfType<CheckBox>()
.Where(c => c.AccessibleName.Equals(checkName)) as CheckBox;
TrackBar tkb = this.Controls.OfType<TrackBar>()
.Where(t => t.AccessibleName.Equals(tbarName)) as TrackBar;
//TrackBar tkb = this.Controls.Find(tbarName, false).First() as TrackBar;
//CheckBox ckb = this.Controls.Find(checkName, false).First() as CheckBox;
if (ckb.Checked == true)
{
//do stuff
}
}
}
what am I doing wrong/really wrong?
Given that you add the checkboxes to your own list:
CheckBoxes.Add(check);
it would be simpler to loop over that rather than trying to find the control associated with the file:
foreach (var checkBox in CheckBoxes)
{
if (checkbox.Checked)
{
// Do stuff...
}
}
However, you shouldn't need to use a separate list. This line is wrong:
CheckBox ckb = this.Controls.OfType<CheckBox>()
.Where(c => c.AccessibleName.Equals(checkName)) as CheckBox;
Where returns a IEnumerable<CheckBox> but you are trying to cast it directly to a CheckBox which will return null. What you should have is:
CheckBox ckb = this.Controls.OfType<CheckBox>()
.Where(c => c.AccessibleName.Equals(checkName)).First();
You will still need to check to see if ckb is null (just in case there is nothing on the list) but this should return you the control you are looking for.
Check the type of "this" and then check its Controls collection - your checkboxes are probably a few iterations down the tree.
You'd need some kind of recursive find controls function such as the one found in this article
Iterating over all the checkboxes with every check is not required and is readlly hard processing work. Instead when creating you always know in what state you've created those - so just keep the count of "Checked" checkboxes. When a checkbox being checked increment the count, and when one unchecked - take out 1 from the count. And later have a check: "if (count == requiredCount) {//Logic here}"
So the code will look like:
private int checkedCount;
private void check_CheckedChanged(Object sender, EventArgs e)
{
this.checkedCount += (sender as CheckBox).Checked?1:-1;
if(this.checkedCount == requiredCount)
{
//do stuff
}
}
Good luck with development.
Goal in mind, the concept is kind of like a shopping cart, so as they add items to list(Detail) it keeps the items they are adding in memory.
This works when ever I first load the list(grid) and add more rows. But if I set the first row and set the item and price and then decide to add 3 more rows then
the info I had added gets deleted instead of keeping its values and just load more lines to the list which would repopulate the gridview.
In the past I have done this with datatables but I want to be able to move from that and use this List Class
Also I have it set as viewstate so I can use it through out my page.
private ListArDocumentdetail Detail
{
get
{
ListArDocumentdetail _detail = new ListArDocumentdetail();
if (ViewState["Detail"] != null)
{
_detail = (ListArDocumentdetail)ViewState["Detail"];
}
return _detail;
}
set
{
ViewState["Detail"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
//creates 2 rows to start off
CreateRows(2);
}
public void CreateRows(int rowstoadd)
{
int newtotalrows = Detail.Count + rowstoadd - 1;
for (int i = Detail.Count; i <= newtotalrows; i++)
{
ArDocumentdetail detail = new ArDocumentdetail();
detail.Lineid = i;
detail.Itemid = 0;
detail.Quantity = 1;
if (Detail.Count > 0)
Detail.Insert(Detail.Count, detail);
else
Detail.Add(detail);
Detail = Detail;
}
gvInvoiceDetail.DataSource = Detail;
gvInvoiceDetail.DataBind();
GridViewRow row = gvInvoiceDetail.Rows[gvInvoiceDetail.Rows.Count - 1];
ImageButton btnAdd = (ImageButton)row.FindControl("btnAdd");
btnAdd.Visible = true;
}
protected void ibAdd_Click(object sender, ImageClickEventArgs e)
{
//user can type in how many rows they want to add on to current amount of rows
//so since grid starts off at 2 and they type 3 the grid refreshes with 5 rows.
CreateRows(Convert.ToInt32(txtRows.Text));
}
protected void UpdateRow(object sender, EventArgs e)
{
ImageButton btnUpdate = sender as ImageButton;
GridViewRow row = btnUpdate.NamingContainer as GridViewRow;
TextBox txtPrice = (TextBox)row.FindControl("txtPrice");
TextBox txtQuantity = (TextBox)row.FindControl("txtQuantity");
DropDownList ddlDescription = (DropDownList)row.FindControl("ddlDescription");
int index = Detail.FindIndex(f => f.Lineid == row.RowIndex);
Detail[index].Itemid = Convert.ToInt32(ddlDescription.SelectedValue);
Detail[index].Price = Convert.ToDecimal(txtPrice.Text);
Detail[index].Subtotal = Convert.ToDecimal(Detail[index].Price * Convert.ToInt32(txtQuantity.Text));
}
I can suggest you the logic:
Push a list into viewstate say Viewstate["List"],
Let a user chose an item. Then List list = (List)Viewstate["List"];
Add the selected item to List list. i.e. list.Add(item);
Now push the item back to viewstate. Viewstate["list"] = list;
Bind it to grid or display it on page. Whatever you want.
I've got a formview whose load event just decided to stop working. I did some debugging and noticed that it was reaching the code, but for whatever reason, the attributes that I am adding in the load event are no longer displaying on the screen. It's as if something is happening after the formview's load event that is reloading it without any of my extra attributes. The only modification that I have done before it stopped working is that I added a session variable in the page before it. That should not cause such a drastic change.
Here is my code:
protected void FormView1_Load(object sender, EventArgs e)
{
RadioButton rbinjury = (RadioButton)FormView1.FindControl("rbinjury");
RadioButton rbproperty = (RadioButton)FormView1.FindControl("rbproperty");
RadioButton rbboth = (RadioButton)FormView1.FindControl("rbboth");
RadioButton rbyes = (RadioButton)FormView1.FindControl("rbyes");
RadioButton rbno = (RadioButton)FormView1.FindControl("rbno");
RadioButton rbyes2 = (RadioButton)FormView1.FindControl("rbyes2");
RadioButton rbno2 = (RadioButton)FormView1.FindControl("rbno2");
RadioButton rbam = (RadioButton)FormView1.FindControl("rbam");
RadioButton rbpm = (RadioButton)FormView1.FindControl("rbpm");
TextBox txtdate = (TextBox)FormView1.FindControl("txtdate");
DropDownList ddlhour = (DropDownList)FormView1.FindControl("ddlhour");
DropDownList ddltime = (DropDownList)FormView1.FindControl("ddltime");
if (FormView1.CurrentMode == FormViewMode.Insert || FormView1.CurrentMode == FormViewMode.Edit)
{
txtdate.Attributes.Add("onfocus", "unfocus();");
locList.Attributes.Add("onChange", "postBack();");
ddlhour.Items.Insert(0, new ListItem("Hour", "0"));
ddlhour.Items.Insert(1, new ListItem("12", "12"));
ddltime.Items.Insert(0, new ListItem("Minute", "0"));
for (int i = 1; i < 12; i++)
{
String hour = Convert.ToString(i);
ddlhour.Items.Add(new ListItem(hour, hour));
}
for (int i = 0; i < 61; i++)
{
String time = "";
if (i < 10)
{
time = ":0" + Convert.ToString(i);
}
else
{
time = ":" + Convert.ToString(i);
}
ddltime.Items.Add(new ListItem(time, time));
}
//-----------------------------------------handle radio buttons----------------------------------------------------------------
rbinjury.Attributes.Add("Onclick", "radio('rbinjury','result');");
rbproperty.Attributes.Add("Onclick", "radio('rbproperty','result');");
rbboth.Attributes.Add("Onclick", "radio('rbboth','result');");
rbyes.Attributes.Add("Onclick", "radio('rbyes','inj');");
rbno.Attributes.Add("Onclick", "radio('rbno','inj');");
rbyes2.Attributes.Add("Onclick", "radio('rbyes2','dmg');");
rbno2.Attributes.Add("Onclick", "radio('rbno2','dmg');");
rbam.Attributes.Add("Onclick", "radio('rbam','time');");
rbpm.Attributes.Add("Onclick", "radio('rbpm','time');");
}}
Any idea what would cause the load event to stop working? If I place this same code in the page's save state complete event, it does work, but I should not have to...
you need to use formview Databound event instead of formview load event to set values, try
using this
protected void frm_DataBound(object sender, EventArgs e)
{
if (frm.CurrentMode == FormViewMode.Edit)
{
TextBox txtdate = (TextBox)frm.FindControl("txtdate");
txtdate.Attributes.Add("", "");
}
}
Also check these threads.
ASP.NET Can not Change Visibility of a Formview control
FormView.FindControl(): object reference error