This question already has answers here:
Method to reset members inside groupBox
(3 answers)
Closed 6 years ago.
I wanna clean my groupbox items after i click an button.
I tried some code blocks, but they don´t work for reset controls.
I don´t wanna remove or delete it, I just wanna reset the items in the groupbox.
This is working for remove groupbox items.
public void ClearPanels(GroupBox control)
{
control.Controls.Clear();
}
or this
groupBox2.Controls.Clear();
It looks like this, before click.
And when I click the button, as you can see on the right side.
It is removed, but I want to reset it.
Any ideas how I can do this ?
I'm going to asume that clear means to leave it all by default. You need to llop all the controls inside the groupbox and depending on what control they are do something or something else.
foreach (Control ctr in GB.Controls)
{
if (ctr is TextBox)
{
ctr.Text = "";
}
else if (ctr is CheckedListBox)
{
CheckedListBox clb = (CheckedListBox)ctr;
foreach (int checkedItemIndex in clb.CheckedIndices)
{
clb.SetItemChecked(checkedItemIndex, false);
}
}
else if (ctr is CheckBox)
{
((CheckBox)ctr).Checked = false;
}
else if (ctr is ComboBox)
{
((ComboBox)ctr).SelectedIndex = 0;
}
}
I dont know what Deneyim and Not are, but i guess you get the idea of checking what it is and asigning the value you want
I think the term clear depends a little on the kind of controls you use. While for a TextBox you probably want to empty the Text property, for a ListBox you probably want to remove all items. So there is no common Clear() method for controls.
What you can do is something like that:
public void ClearPanels(GroupBox control)
{
foreach(Control childControl in control.Controls)
childControl.ResetText();
}
This iterates through all child Controls in your GroupBox and resets the Text property of them. You may wish to add special treatment for certain types of Control.
If your GroupBox contains nested controls (such as another GroupBox with further controls on it), you may need to make this method recursive:
public void ClearPanels(Control control)
{
foreach(Control childControl in control.Controls)
{
childControl.ResetText();
ClearPanels(childControl); // recursive call
}
}
To really "clear" your controls, you have to check their specific type. So a little advanced method could be this:
public void ClearPanels(GroupBox control)
{
foreach(ListBox listBox in control.Controls.OfType<ListBox>())
{
listBox.Items.Clear();
// do more ListBox cleanup
}
foreach(CheckedListBox listBox in control.Controls.OfType<CheckedListBox>())
{
listBox.Items.Clear();
// do more CheckedListBox cleanup
}
foreach(ListView listView in control.Controls.OfType<ListView>())
{
listView.Items.Clear();
// do more ListView cleanup
}
foreach(CheckBox checkBox in control.Controls.OfType<CheckBox>())
{
checkBox.Checked = false;
// do more CheckBox cleanup
}
// etc...
}
Related
My current function only finds first Textbox which is not totally correct. Control class doesn't have IsEditable property.
private static Control FindFocusableControl(Control CurrentControl)
{
if (CurrentControl.Visible)
{
if (CurrentControl is TextBox)
{
return CurrentControl;
}
if (CurrentControl.HasControls())
{
foreach (Control CurrentChildControl in CurrentControl.Controls)
{
Control focusableControl = FindFocusableControl(CurrentChildControl);
if (focusableControl != null)
{
return focusableControl;
}
}
}
}
return null;
}
On the first recursion for the first child control, the child control is probably not visible so the routine exits.
if (CurrentControl.Visible)
You might need a different kind of check at this point, perhaps check for textbox first, then if visible.
I have a windows form that just exists to take input from user, for all intents and purposes it is just a label and a corresponding input box (textbox, checkbox, masket textbox etc).
I have programatically placed all the input fields in a TabIndex order that is optimal for cycling through them in a way that fits with their locations (tab down each column of inputs, then to the top of the next column).
The person that I am building this project for has stipulated that only like each textbox to come available one at a time, as the previous one has been filled out. This is a crude way of doing it with no validation, but essentially something like this...
if (String.IsNullOrEmpty(textbox1.Text))
{
textbox2.Enabled = true
}
So this is fine to do with two textboxes in this example, but the form has 28 different inputs on it, so an absurd series of if statements will only be a last resort.
My thoughts has been to put all the inputs in a List, ideally in the same order as is their TabIndexes. I tried to do this using a foreach loop...
List<Control> inputsList = new List<Control>();
public void initialiseControls()
{
//control position to insert control into list at specified index
int cntrlpos = 0;
//for every control in form
foreach (Control cntrl in this.Controls)
{
//not counting labels (not input fields)
if (!(cntrl is Label))
{
//set list position to equal control's TabIndex
cntrlpos = cntrl.TabIndex;
//insert the control into the list at the position reflecting TabIndex
inputsList.Insert(cntrlpos, cntrl); //<---- Error Occurs
//ASK TEXTBOX TO OUTPUT LIST POSITION AS TEST
//foreach (var txtbx in this.Controls.OfType<TextBox>())
//{
// txtbx.Text = Convert.ToString(cntrlpos);
//}
}
}
As soon as the function is called, an exception is thrown stating that "Index must be within the bounds of the list".
When I put a breakpoint into the code, it showed cntrlpos to equal 29, which is more than the 28 total input controls there are on the form.
I don't know where to go from here, if anyone can offer some advice on the code above to place the Controls into the list in the correct order (or point me in the direction of another method to do something like this), then I would really appreciate it.
Thanks,
Mark
To make your list, try this:
List<Control> inputList =
(from Control c in getAllControls(this)
where c.TabStop
orderby c.TabIndex
select c).ToList();
Define the method getAllControls elsewhere in your form class:
IEnumerable<Control> getAllControls(Control parent)
{
foreach (Control control in parent.Controls)
{
yield return control;
foreach (Control descendant in getAllControls(control))
yield return descendant;
}
}
(Taken and modified slightly from Recursive control search with Linq)
This will make it so that you get even nested controls (such as those in panels or groupboxes).
You can't just use the TabIndex as an index into your list, because even stuff like labels have tab indices, which will mess up your indices.
I think you've over complicated it...
Just use Control.GetNextControl:
Retrieves the next control forward or back in the tab order of child
controls.
For example, with just TextBoxes:
private void textBoxes_TextChanged(object sender, EventArgs e)
{
Control ctl = (Control)sender;
if (!String.IsNullOrEmpty(ctl.Text))
{
Control next = this.GetNextControl(ctl, true);
if (next != null)
{
next.Enabled = true;
}
}
}
Obviously you might need a slightly more complicated check for some other types of controls in a different handler, but you'd still just grab the next control to enable using GetNextControl().
I wrote this code to make all controls readonly.
makeReadOnly(Control control, bool bIsReadOnly)
{
for(int i=0; i< control.Controls.Count; i++)
{
if(control.Controls[i].Controls.Count > 0)
{
makeReadOnly(control.Controls[i], bIsReadOnly);
}
else if(control.Controls[i].GetType() == typeof(UltraTextEditor))
{
(control.Controls[i] as UltraTextEditor).ReadOnly = bIsReadOnly;
}
else if(control.Controls[i].GetType() == typeof(UltraNumericEditor))
{
(control.Controls[i] as UltraNumericEditor).ReadOnly = bIsReadOnly;
}
else if(control.Controls[i].GetType() == typeof(ListBox))
{
(control.Controls[i] as ListBox).Enable = !bIsReadOnly;
}
}
}
It works but if user clicks one control such as a textbox, then click edit button(call makeReadOnly function). Function does not work for the clicked textbox. (It works for the other controls only).
Private void EditButton_Click()
{
foreach(Controls control in this.controls)
{
makeReadOnly(control, false);
}
}
"this" represents parent form."EditButton_Click()" is button event.
Why it is not working for the clicked ones?
How can I solve this problem?
I think, I found the answer. The problem is in Infragistics controls. When a user clicks an UltraTextEditor or UltraComboEditor controls, Infragistics changes its type to something like "EmbeddableUIText..." and its parent type becomes UltraTextEditor or UltraComboEditor. So, I have to check this types or controls' parent types to solve it.
How can we change the ReadOnly property of all textBoxes in a winform that is true to false i'm trying using this code but this prompt me object null reference error...
private void TextBoxesReadOnlyTrue(Control.ControlCollection cc)
{
foreach (Control ctrl in cc)
{
TextBox tb = ctrl as TextBox;
if (tb.ReadOnly)
{
tb.ReadOnly = false;
}
}
}
That's because not all the controls in cc are TextBoxes. So when you try converting them to a TextBox, the variable is null. When a variable is null, you cannot access any properties on that variable, or you'll get an error. So anytime a variable can be null, you MUST first test whether it is null.
Here's the modified if command that you'll want to use to fix your problem:
if (tb != null && tb.ReadOnly) { tb.ReadOnly = false; }
So i appologize that i overlooked that your TextBoxes can be contained in other container controls. Yes, that means you need to do 1 of 2 things: 1: You can move the TextBoxes outside the GroupBox. haha. I'm just joking. Yes, that can solve that problem but then you have worse problems. The correct way is to recursively call your method for every control that has controls in its Controls property. Every control has this property but it seems it is empty (but not null) in controls that are not containers. (I just learned today that every control has this Controls property, so i've updated my code to reflect this.)
So for this real solution, i suggest something similar to this:
private void TextBoxesReadOnlyTrue(Control.ControlCollection cc)
{
foreach (Control ctrl in cc)
{
TextBox tb = ctrl as TextBox;
if (tb != null && tb.ReadOnly)
{ tb.ReadOnly = false; continue; }
if (ctrl.Controls != null && ctrl.Controls.Count > 0)
{ TextBoxesReadOnlyTrue(ctrl.Controls); }
// this recursively calls this same method for every control ...
// that is a container control that contains more controls, ...
// such as GroupBoxes, Panels, etc.
}
}
first you would like to use a function like this:
Recursive get controls
then you do the following
private IEnumerable<T> GetControls<T>(Control.ControlCollection ctrls)
{
foreach (object ctrl in ctrls)
{
foreach (var item in GetControls<T>(((Control)ctrl).Controls))
{
yield return item;
}
if (ctrl is T)
yield return (T)ctrl;
}
}
foreach(var txtbox in GetControls<TextBox>(form.Controls)
{
txtbox.ReadOnly = false;
}
I want to iterate through various controls of update panel. While iterating using ID for control I want to delete some of the controls.
But I don't know how to iterate through controls of update panel using GetEnumerator method?
If we can do iteration by some other way, please let me know.
Couldn't you loop over the Controls collection of the updatepanel:
foreach(var control in myUpdatePanel.Controls) {
...
}
You can loop the ControlCollection.
Just remember that these controls can be nested, if they are in panels eg.
private void RecusiceControls(ControlCollection controls)
{
foreach (Control control in controls)
{
RecusiceControls((ControlCollection)control.Controls);
if (control is Button) // whatever the control is you are looking for
{
}
}
}