I have a Repeater control that is creating a dynamic amount of CheckBoxList controls and each list has a different set of ListItems.
I have done this part just fine, but the issue I'm having is how to save the checked states of these dynamically created boxes. I cannot find out how to get the list of these CheckBoxList controls.
Here's some pseudo-code of what I'm trying to do:
foreach (Item i in MyRepeater)
{
if (i.ItemType is CheckBoxList)
{
foreach (ListItem x in i)
{
update table set tiChecked = x.Checked
where table.id = i.id and table.typeid = x.id
}
}
}
I have the ID of the CheckBoxList and the ListItem corresponding to the IDs in the DB.
Edit:
Of course after I ask, I find it out. This seems to be getting me what I want
foreach (RepeaterItem tmp in rptReportList.Items)
{
if (tmp.ItemType == ListItemType.Item)
{
foreach (Control c in tmp.Controls)
{
if (c is CheckBoxList)
{
DisplayMessage(this, c.ID.ToString());
}
}
}
}
You need to look deeper than the RepeaterItem:
// repeater item
foreach (Control cr in MyRepeater.Controls)
{
// controls within repeater item
foreach (Control c in cr.Controls)
{
CheckBoxList chklst = c as CheckBoxList;
if (chklst != null)
{
foreach (ListItem i in chklst.Items)
{
string valueToUpdate = i.Value;
string textToUpdate = i.Text;
bool checkedToUpdate = i.Selected;
// Do update
}
}
}
}
Related
When I double click on my selected listview item I can easily get each value and set them in a textbox by using the following code.
ListViewItem item = listView1.SelectedItems[0];
entry_txtBox.Text = item.Text;
name_txtBox.Text = item.SubItems[1].Text;
But I'd rather loop through the selected item and compare each column name to each textbox tag. If they match set the column value to the textbox.
This is what I have so far.
foreach (Control c in this.Controls)
{
foreach (Control childc in c.Controls)
{
foreach (ColumnHeader header in listView1.Columns) // This should be the selected item.
{
if (childc is TextBox && header == childc.Tag)
{
// Fill Textboxes
}
}
}
}
Again my question is how can I loop through each column header and compare them to a textbox tag.
First you can use good old recursion to build a flat list of all your controls up by traversing the control tree:
var controls = GetControls(parent);
public IEnumerable<Control> GetControls(Control parent)
{
foreach(var control in parent.Controls)
{
yield return control;
var childControls = GetControls(control);
foreach(var child in childControls)
{
yield return child;
}
}
}
Then just do a LINQ to filter:
var textBoxControls = controls.Select(c => c is TextBox && header == TextBox.ID); //Or whatever condition you want to use.
I have a listview in C# with columns(ProdcutId,ProductName,UnitPirce,Quantity). I am inserting data in it from text boxes(txtproid,txtproname,txtunitprice,txtquantity). All these txtboxes are inserted once on a button click. What I want here is when i click the button,it should check the ProductId column in listview. If it contain the value coming from 'txtproid', It should not add all txtboxes in listview instead should show a messaage "This Product is Already Included". It should not check the whole item in listv.
I have tried many things but invain like:
int c = 0;
if (listView1.Items.Count != 0)
{
foreach (ListViewItem lv in listView1.Items)
{
c = 0;
if (lv.SubItems[0].Text == cmbpid.SelectedItem.ToString())
{
Validations.ErrorMessage("Item already exists in the Cart");
c = 1;
}
}
}
else if (c == 0)
{
ListViewItem lvi = new ListViewItem(cmbpid.Text);
lvi.SubItems.Add(cmbpname.Text);
lvi.SubItems.Add(txtunitprice.Text);
lvi.SubItems.Add(txtproquantity.Text);
lvi.SubItems.Add(txtunittotal.Text);
lvi.SubItems.Add(txtbatch.Text);
listView1.Items.Add(lvi);
//clear fields
quvar = 0;
totalvar = 0;
txtproquantity.Clear();
txtunitprice.Clear();
txtunittotal.Clear();
GetListviewTotal();
txtbatch.Clear();
cmbpid.SelectedIndex = -1;
cmbpname.SelectedIndex = -1;
}
Your task is divided two small functions.
First, check duplicate product id.(Let's say CheckSameProductId())
Second, insert data to ListView.(Let's say InsertProductData())
So, below form can be.
if (CheckDuplicateId())
{
//show error text
}
else
{
//insert text boxes's data to List View
InsertProductData();
}
And then, each function can write, for example.
//check whether it's already inserted
bool CheckDuplicateId()
{
foreach (ListViewItem lv in listView1.Items)
{
if (lv.SubItems[0].Text == cmbpid.SelectedItem.ToString())
{
//there is a duplicate data
return true;
}
}
//there is no duplicate data
return false;
}
//insert data using text boxes to listview ctrl
void InsertProductData()
{
foreach (Control x in this.Controls)
{
if (x is TextBox)
{
//I'm not sure your control z-order
lvi.SubItems.Add(((TextBox)x).Text);
}
}
}
I've not compiled above code, so you have to check that.
I am having 40 combo-box in my win-form application, I want to check at end on button click that all the combo-box value has been entered i.e no combo-box value has been selected empty
i am trying below code using for each loop but cant find success
foreach (Control c in this.Controls)
{
if (c is ComboBox)
{
ComboBox textBox = c as ComboBox;
if (textBox.SelectedValue==string.Empty)
{
MessageBox.Show("please fill all fields");
}
}
}
so how to achieve this validation in simple lines of codes
Try to use linq and a recursion:
var isAnyEmpty = ScanForControls<ComboBox>(this)
.Where(x => x.SelectedIndex < 0)
.Any();
if (isAnyEmpty)
MessageBox.Show("please fill all fields");
And recursion search:
public IEnumerable<T> ScanForControls<T>(Control parent) where T : Control
{
if (parent is T)
yield return (T)parent;
foreach (Control child in parent.Controls)
{
foreach (var child2 in ScanForControls<T>(child))
yield return (T)child2;
}
}
To make sure that you check each & every ComboBox in your Form you will have to iterate over each control in you Form, Try this for that.
private void button1_Click(object sender, EventArgs e)
{
foreach (Control c in this.Controls)
{
if (c is ComboBox)
{
ComboBox textBox = c as ComboBox;
if (textBox.SelectedValue == null)
{
MessageBox.Show("please fill all fields");
break;
}
}
else
recursiveComboboxValidator(c);
}
}
void recursiveComboboxValidator(Control cntrl)
{
foreach (Control c in cntrl.Controls)
{
if (c is ComboBox)
{
ComboBox textBox = c as ComboBox;
if (textBox.SelectedValue == null)
{
MessageBox.Show("please fill all fields");
break;
}
}
else
recursiveComboboxValidator(c);
}
}
I have a C# form with some types of controls, i throught this code for loop all Labels and re-parent:
private void MakeAllLabelTrans(Control frm, Control parent)
{
foreach (Control ctl in frm.Controls)
{
if (ctl is Label)
{
ctl.Parent = parent;
// ctl.BackColor = Color.Transparent;
}
else if (ctl.HasChildren)
{
MakeAllLabelTrans(ctl, parent);
}
}
}
and call as: MakeAllLabelTrans(this, picBackground); in Form_Load event, but some label was missed (i have puted a messagebox in the loop body - it really not in the loop), but i don't know why?
You're changing the collection while enumerating it. This leads to some items being skipped.
You should rewrite this to first build a list of controls that will need to be reparented, and then reparent them in a second pass.
You should not modify the collection on which you are iterating.
private static IEnumerable<Labels> FindAllLabels(Control container)
{
foreach (Control ctl in container.Controls)
{
var lbl = ctl as Label;
if (lbl != null)
{
yield return ctl;
}
else if (ctl.HasChildren)
{
foreach (var innerResult in FindAllLabels(ctl))
yield return innerResult;
}
}
}
// now call the method like this if you want to change a property on the label
foreach (var label in FindAllLabels(theForm))
label.BackgroundColor = Color.White;
// or like this (note the .ToList()) if you want to move the labels around:
foreach (var label in FindAllLabels(theForm).ToList())
label.Parent = someOtherControl;
I have a asp.net page which is inherited from a master page .I want to clear all controls in this page .I tried using the bellow method .This is not working if a master page is there. Otherwise its working fine any ideas?
private void ClearControls()
{
foreach(Control c in Page.Controls)
{
foreach (Control ctrl in c.Controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).Text = string.Empty;
}
}
}
}
try this:
public void FindAllTextBox(Control ctrl)
{
if (ctrl != null)
{
foreach (Control c in ctrl.Controls)
{
if (c is TextBox)
((TextBox)c).Text = string.empty;
FindAllTextBox(c);
}
}
}
Ex.:
Control ctrl = this.FindControl("content");
FindAllTextBox(ctrl);
You should be able to do this with Page.Form.FindControl("ContentPlaceHolder1").Controls:
foreach (Control item in Page.Form.FindControl("ContentPlaceHolder1").Controls)
{
if (item is TextBox)
{
((TextBox)item).Text = string.Empty;
}
}
This is probably because of your controls are inside of another container when you add a master page. Have you tried adding another foreach before if?
private void ClearControls()
{
foreach(Control container in Page.Controls)
{
foreach (Control c in container.Controls)
{
foreach (Control ctrl in c.Controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).Text = string.Empty;
}
}
}
}
}
I wouldn't do it this way though. Sometimes hardcoding is better. This would use a lot of resource when called on a page that contains lots of controls.
Don't hard code:
//Recursively get all the formControls underneath the current one, be it Page, UserControl or whatever.
public static IEnumerable<Control> GetAllControls(this Control parent)
{
foreach (Control control in parent.Controls)
{
yield return control;
foreach (Control descendant in control.GetAllControls())
{
yield return descendant;
}
}
}
Then you can call it in your webform / control:
var formCtls = this.GetAllControls().OfType<TextBox>();
foreach(TextBox txtbx in formCtls)
{
//do what you gotta do ;)
}
First, use operator as instead of is and cast:
TextBox tb = ctrl as TextBox;
if (tb != null)
{
tb.Text = String.Empty;
}
Second, you can use ITextControl instead of TextBox.
And third, try next extension method:
public static IEnumerable<T> GetChildControls(this Control control) where T : Control
{
var children = (control.Controls != null) ? control.Controls.OfType<T>() : Enumerable.Empty<T>();
return children.SelectMany(c => GetChildControls(c)).Concat(children);
}
Usage:
foreach (var c in this.Page.Controls.GetChildControls<TextBox>())
{
c.Text = String.Empty;
}
I had the same problem but I think I was making it too hard. I'm using an AJAX UpdatePanel control and I just referenced that instead of going all the way up to the MasterPage. This worked for me.
foreach (Control c in UpdatePanel1.Controls)
{
foreach (Control c1 in c.Controls)
{
if (c1 is TextBox)
{
TextBox txtBox = (TextBox)c1;
txtBox.Text = "0";
}
}
}
Just keep the controls in Panel, and try the code below
foreach (Control cntrl in pnl.Controls)//pnl is panel id
{
if (cntrl is TextBox)
{
TextBox txtBox = (TextBox)cntrl;
txtBox.Text = " ";
}
}
Make a method on your .cs like this:
//Where "this" is Page.
ClearInput(this);
private void ClearInput(Control parent)
{
foreach (Control c in parent.Controls)
{
if (c.Controls.Count > 0)
ClearInput(c);
else
{
if (c is TextBox)
(c as TextBox).Text = "";
if (c is CheckBox)
(c as CheckBox).Checked = false;
if (c is DropDownList)
(c as DropDownList).SelectedIndex = 1;
}
}
}
private void EnableControls(Control control)
{
var textbox = control as TextBox;
if (textbox != null)
{
textbox.Enabled = true;
}
var dropDownList = control as DropDownList;
if (dropDownList != null)
{
dropDownList.Enabled = true;
}
var radioButton = control as RadioButton;
if (radioButton != null)
{
radioButton.Enabled = true;
}
var checkBox = control as CheckBox;
if (checkBox != null)
{
checkBox.Enabled = true;
}
foreach (Control childControl in control.Controls)
{
EnableControls(childControl);
}
}
public void getAllCtl(ControlCollection ctls)
{
foreach (Control c in ctls)
{
if (c is System.Web.UI.WebControls.TextBox)
{
//TextBox tt = c as TextBox;
////to do something by using textBox tt.
((TextBox)c).Text = string.Empty;
}
if (c is System.Web.UI.WebControls.CheckBox)
{
((CheckBox)c).Checked = false;
}
if (c is System.Web.UI.WebControls.DropDownList)
{
((DropDownList)c).SelectedIndex = -1;
}
if (c.HasControls())
{
getAllCtl(c.Controls);
}
}
}
calling in aspx.cs file as
getAllCtl(this.Form.Controls);
This is OK and tested work for all Master-child page and where ever multiple controls are contains in the page...