How can I loop thru all controls (including ToolStripItems) C# - c#

I need to save and restore settings for specific controls on a form.
I loop thru all controls and return the one whose name matches the one I want, like so:
private static Control GetControlByName(string name, Control.ControlCollection Controls)
{
Control thisControl = null;
foreach (Control c in Controls)
{
if (c.Name == name)
{
thisControl = c;
break;
}
if (c.Controls.Count > 0)
{
thisControl = GetControlByName(name, c.Controls);
if (thisControl != null)
{
break;
}
}
}
return thisControl;
}
From this I can determine the type of control and therefore the property that should be / has been stored.
This works well unless the control is one of the ToolStrip family which has been added to a toolstrip. e.g.
this.toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.lblUsername, // ToolStripLabel
this.toolStripSeparator1,
this.cbxCompany}); // ToolStripComboBox
In this case I can see the control I'm interested in (cbxCompany) when debugging, but the name property has no value so the code does not match to it.
Any suggestions on how I can get to these controls too?
Cheers,
Murray

Thanks for your help guys.
Pinichi set me on the right track, I was checking toolStrip.Controls - should have been toolStrip.Items
The code below now works perfectly for me:
private static Control GetControlByName(string controlName, Control.ControlCollection parent)
{
Control c = null;
foreach (Control ctrl in parent)
{
if (ctrl.Name.Equals(controlName))
{
c = ctrl;
return c;
}
if (ctrl.GetType() == typeof(ToolStrip))
{
foreach (ToolStripItem item in ((ToolStrip)ctrl).Items)
{
if (item.Name.Equals(controlName))
{
switch (item.GetType().Name)
{
case "ToolStripComboBox":
c = ((ToolStripComboBox)item).Control;
break;
case "ToolStripTextBox":
c = ((ToolStripTextBox)item).Control;
break;
}
if (c != null)
{
break;
}
}
}
}
if (c == null)
c = GetControlByName(controlName, ctrl.Controls);
else
break;
}
return c;
}

Try This:
//for toolstrip
if (ctrl is ToolStrip)
{
ToolStrip ts = ctrl as ToolStrip;
foreach (ToolStripItem it in ts.Items)
{
if (it is ToolStrienter code herepSeparator)
{
//-------------------------
}
else
{
//do something
}
}
}//---------------

Related

C# CheckBox Checked value cannot change if clicked manually on the form

So I do loop over the form and check "checked" value for all checkboxes. Every time I get "Unchecked" back even if the checkbox is checked on the form.
here is how i loop
public class FindAll
{
public IEnumerable<Control> GetAllChildren(Control root)
{
var stack = new Stack<Control>();
stack.Push(root);
while (stack.Any())
{
var next = stack.Pop();
foreach (Control child in next.Controls)
stack.Push(child);
yield return next;
}
}
}
and here how i determine checked state
public List<string> Checked()
{
List<string> checkedList = new List<string>();
var all = new FindAll();
foreach (var checkbox in all.GetAllChildren(tabPage4).OfType<CheckBox>())
{
checkedList.Add(checkbox.CheckState.ToString());
}
for (int i = 0; i < 22; i++)
{
MessageBox.Show(checkedList.ElementAt(i));
}
return checkedList;
}
no matter if i chech the checkboxes on the form while app is running. i always get "unchecked" value.
Hardcoded:
foreach (Control c in tabPage4.Controls)
{
if (c is GroupBox)
{
foreach (Control d in c.Controls)
{
var e = d as CheckBox;
if (e != null)
{
MessageBox.Show(d.Name + " " + e.Checked);
checkedList.Add(d.Name, e.Checked.ToString());
}
}
}
}

get all control from multiple form in csharp

I want to get all the control from multiple form (Main, Two and Three) and
compare if the control tag equals the variable str_name and if true write the
value of str_value in c.Text.
the code:
private static Form[] getformular()
{
Main main = new Main();
Two f2 = new Two();
Three f3 = new Three();
Form[] form = { main, f2, f3};
return form;
}
private void initcontrol()
{
String str_name = "name";
String str_value = "value";
foreach(Form f in getformular())
{
foreach (Control c in f.Controls)
{
if (f != null && c = null)
{
if (c.Tag.Equals(str_name))
{
c.Text = str_value;
}
}
}
}
}
Could please someone help me?
First, as stated by #JonB some of conditional checking (ifs logic) in your current code seems off.
Second, looping through Form.Controls will only bring you all controls placed directly in the Form. For example if you have tab control (or any other container control) placed in form, and you have a textbox inside that tab control, you'll get only the tab control and couldn't find the textbox by looping through Form.Controls. You can solve that with recursive method as demonstrated below.
private void initcontrol()
{
String str_name = "name";
String str_value = "value";
var result = false;
foreach(Form f in getformular())
{
//if you want to check if f null, it should be here.
if(f != null) result = setControlText(f, str_name, str_value);
}
if(!result) MessageBox.Show("Control not found");
}
private bool setControlText(Control control, string str_name, string str_value)
{
var isSuccess = false;
foreach (Control c in control.Controls)
{
//if c is not null
if (c != null)
{
//check c's Tag, if not null and matched str_name set the text
if (c.Tag != null && c.Tag.Equals(str_name))
{
c.Text = str_value;
isSuccess = true;
}
//else, search in c.Controls
else isSuccess = setControlText(c, str_name, str_value);
//if control already found and set, exit the method now
if (isSuccess) return true;
}
}
return isSuccess;
}

how to get value of more than one text box in a loop

I have some text boxes in my page. I want to get all text box values in an array and insert in to table of database.
Is there any option to work by loop
public IEnumerable<string> AllTextsFromTextboxes()
{
foreach (var control in Page.Controls.OfType<TextBox>())
{
yield return control.Text;
}
}
you can try something on these lines, if all the textbox are on the page directly
foreach(Control c in Page.Controls)
{
if (c is TextBox)
{
//get the text
}
}
This will not work for child controls for that you will have to recursively iterate
yes, you can put your controls in panel and then iterate and get value. e.g.
foreach (Control ctrl in Panel1.Controls)
{
if (ctrl.GetType().Name == "TextBox")
{
if (((TextBox)ctrl).Text != string.Empty)
{
// do stuff here
}
}
}
private void FindSelecedControl(Control control)
{
if (control is TextBox)
{
TextBox txt = (TextBox)control;
txt.Enabled = false;
}
else
{
for (int i = 0; i < control.Controls.Count; i++)
{
FindSelecedControl(control.Controls[i]);
}
}
}
foreach (Control control1 in this.Form.Controls)
{
FindSelecedControl(control1);
}

finding all the HtmlInputCheckBox controls with master.pages with recursion

I thought this would work. But it's not working. It's never getting inside of if (c is HtmlInputCheckBox)
private string GetAllCheckBoxes(ControlCollection controls)
{
StringBuilder sb = new StringBuilder();
foreach (Control c in controls)
{
if (c.HasControls())
{
GetAllCheckBoxes(c.Controls);
}
else
{
if (c is HtmlInputCheckBox)
{
CheckBox cb = c as CheckBox;
if (cb.Checked)
{
sb.Append(cb.ID + "_1");
}
else
{
sb.Append(cb.ID + "_0");
}
}
}
}
return sb.ToString();
}
update: c is throwing somesort of error.
Parent = {InnerText = '((System.Web.UI.HtmlControls.HtmlContainerControl)(((System.Web.UI.HtmlControls.HtmlGenericControl)(c.Parent)))).InnerText' threw an exception of type 'System.Web.HttpException'}
HtmlInputCheckBox and CheckBox are different classes and do not inherit from the other. An is test on one won't work for the other and vice versa. Sounds like the control is probably an instance of a CheckBox so change the conditional to:
if (c is CheckBox)

Foreach Control in form, how can I do something to all the TextBoxes in my Form?

How can I use a Foreach Statement to do something to my TextBoxes?
foreach (Control X in this.Controls)
{
Check if the controls is a TextBox, if it is delete it's .Text letters.
}
If you are using C# 3.0 or higher you can do the following
foreach ( TextBox tb in this.Controls.OfType<TextBox>()) {
..
}
Without C# 3.0 you can do the following
foreach ( Control c in this.Controls ) {
TextBox tb = c as TextBox;
if ( null != tb ) {
...
}
}
Or even better, write OfType in C# 2.0.
public static IEnumerable<T> OfType<T>(IEnumerable e) where T : class {
foreach ( object cur in e ) {
T val = cur as T;
if ( val != null ) {
yield return val;
}
}
}
foreach ( TextBox tb in OfType<TextBox>(this.Controls)) {
..
}
You're looking for
foreach (Control x in this.Controls)
{
if (x is TextBox)
{
((TextBox)x).Text = String.Empty;
}
}
The trick here is that Controls is not a List<> or IEnumerable but a ControlCollection.
I recommend using an extension of Control that will return something more..queriyable ;)
public static IEnumerable<Control> All(this ControlCollection controls)
{
foreach (Control control in controls)
{
foreach (Control grandChild in control.Controls.All())
yield return grandChild;
yield return control;
}
}
Then you can do :
foreach(var textbox in this.Controls.All().OfType<TextBox>)
{
// Apply logic to the textbox here
}
Also you can use LINQ. For example for clear Textbox text do something like:
this.Controls.OfType<TextBox>().ToList().ForEach(t => t.Text = string.Empty);
foreach (Control X in this.Controls)
{
if (X is TextBox)
{
(X as TextBox).Text = string.Empty;
}
}
You can do the following:
foreach (Control X in this.Controls)
{
TextBox tb = X as TextBox;
if (tb != null)
{
string text = tb.Text;
// Do something to text...
tb.Text = string.Empty; // Clears it out...
}
}
A lot of the above work.
Just to add. If your textboxes are not directly on the form but are on other container objects like a GroupBox, you will have to get the GroupBox object and then iterate through the GroupBox to access the textboxes contained therein.
foreach(Control t in this.Controls.OfType<GroupBox>())
{
foreach (Control tt in t.Controls.OfType<TextBox>())
{
// do stuff
}
}
Just add other control types:
public static void ClearControls(Control c)
{
foreach (Control Ctrl in c.Controls)
{
//Console.WriteLine(Ctrl.GetType().ToString());
//MessageBox.Show ( (Ctrl.GetType().ToString())) ;
switch (Ctrl.GetType().ToString())
{
case "System.Windows.Forms.CheckBox":
((CheckBox)Ctrl).Checked = false;
break;
case "System.Windows.Forms.TextBox":
((TextBox)Ctrl).Text = "";
break;
case "System.Windows.Forms.RichTextBox":
((RichTextBox)Ctrl).Text = "";
break;
case "System.Windows.Forms.ComboBox":
((ComboBox)Ctrl).SelectedIndex = -1;
((ComboBox)Ctrl).SelectedIndex = -1;
break;
case "System.Windows.Forms.MaskedTextBox":
((MaskedTextBox)Ctrl).Text = "";
break;
case "Infragistics.Win.UltraWinMaskedEdit.UltraMaskedEdit":
((UltraMaskedEdit)Ctrl).Text = "";
break;
case "Infragistics.Win.UltraWinEditors.UltraDateTimeEditor":
DateTime dt = DateTime.Now;
string shortDate = dt.ToShortDateString();
((UltraDateTimeEditor)Ctrl).Text = shortDate;
break;
case "System.Windows.Forms.RichTextBox":
((RichTextBox)Ctrl).Text = "";
break;
case " Infragistics.Win.UltraWinGrid.UltraCombo":
((UltraCombo)Ctrl).Text = "";
break;
case "Infragistics.Win.UltraWinEditors.UltraCurrencyEditor":
((UltraCurrencyEditor)Ctrl).Value = 0.0m;
break;
default:
if (Ctrl.Controls.Count > 0)
ClearControls(Ctrl);
break;
}
}
}
foreach (Control x in this.Controls)
{
if (x is TextBox)
{
((TextBox)x).Text = String.Empty;
//instead of above line we can use
*** x.resetText();
}
}
Check this:
foreach (Control x in this.Controls)
{
if (x is TextBox)
{
x.Text = "";
}
}
simple using linq, change as you see fit for whatever control your dealing with.
private void DisableButtons()
{
foreach (var ctl in Controls.OfType<Button>())
{
ctl.Enabled = false;
}
}
private void EnableButtons()
{
foreach (var ctl in Controls.OfType<Button>())
{
ctl.Enabled = true;
}
}
Even better, you can encapsule this to clear any type of controls you want in one method, like this:
public static void EstadoControles<T>(object control, bool estado, bool limpiar = false) where T : Control
{
foreach (var textEdits in ((T)control).Controls.OfType<TextEdit>()) textEdits.Enabled = estado;
foreach (var textLookUpEdits in ((T)control).Controls.OfType<LookUpEdit>()) textLookUpEdits.Enabled = estado;
if (!limpiar) return;
{
foreach (var textEdits in ((T)control).Controls.OfType<TextEdit>()) textEdits.Text = string.Empty;
foreach (var textLookUpEdits in ((T)control).Controls.OfType<LookUpEdit>()) textLookUpEdits.EditValue = #"-1";
}
}
private IEnumerable<TextBox> GetTextBoxes(Control control)
{
if (control is TextBox textBox)
{
yield return textBox;
}
if (control.HasChildren)
{
foreach (Control ctr in control.Controls)
{
foreach (var textbox in GetTextBoxes(ctr))
{
yield return textbox;
}
}
}
}
I found this to work very well, but initially I have my textboxes on a panel so none of my textboxes cleared as expected so I added
this.panel1.Controls.....
Which got me to thinking that is you have lots of textboxes for different functions and only some need to be cleared out, perhaps using the multiple panel hierarchies you can target just a few and not all.
foreach ( TextBox tb in this.Controls.OfType<TextBox>()) {
..
}

Categories