Forms : Enabled/Disable all controls in a container (panel) - c#

I am coding a C# Forms application and would like to know how to enable/disable all controls container within a panel.
Here is my code:
private void EnabledPanelContents(Panel panel, bool enabled)
{
foreach (var item in panel.Controls)
{
item.enabled = enabled;
}
}
There is no enabled property in the panel.Controls collection.
How can I enable/disable all controls container within a panel.
Thanks in advance.

You are getting controls as var and iterating on them and var doesn't contain any property Enabled. You need to loop through controls and get every control as Control. Try this
private void EnabledPanelContents(Panel panel, bool enabled)
{
foreach (Control ctrl in panel.Controls)
{
ctrl.Enabled = enabled;
}
}
Enabled can be true or false.

"How can I enable/disable all controls container within a panel."
A:
If you want to disable or enable all controls within a panel, you can directly call,
Panel panel;
-> panel.Enabled = true;//For enabling all controls inside the panel.
-> panel.Enabled = false;//For disabling all controls inside the panel.
If you want only specific controls inside the panel to be enabled or disabled then you can iterate through the collection of controls and set it's enable state to true or false based on your requirement.

If you declare item as var (in the foreach loop), it won't have the properties of a windows control.
You should declare it as a control.
Try this code snippet and it should work:
foreach (Control item in panel.Controls)
{
item.Enabled = true; // = true: enable all, = false: disable all
}

Try the following code,
private void DisableAll_Click(object sender, EventArgs e)
{
EnabledPanelContents(this.panel1, false);
}
private void EnabledPanelContents(Panel panel, bool enabled)
{
foreach (Control item in panel.Controls)
{
item.Enabled= enabled;
}
}

#anshu
if your controls are HTML controls then use
foreach (Control ctrl in myControl1.Controls)
if (ctrl is HtmlControl)
((HtmlControl)ctrl).Disabled = true;

private void Form1_Load(object sender, EventArgs e)
{
foreach (Control item in panel.Controls)
if (ctrl is Button)
((Button)item).Enabled = false;
}

Related

Iterating through checkboxes inside different panels that are inside a parent panel

So I am making a "Disable all checked checkboxes" button for my windows form application in c#. The code I have works fine when set to loop through a specific panel, like so:
private void LockChecked_Click(object sender, EventArgs e)
{
foreach (Control c in block1Panel.Controls)
{
if (c is CheckBox)
{
CheckBox cb = (CheckBox)c;
if (cb.Checked == true)
{
cb.Enabled = false;
}
}
}
}
But what I'd like to do is loop through all the block panels (block1Panel, block2Panel, block3Panel, etc.) that are inside a main panel (Assignments_Panel).
So, how can I iterate through all the checkboxes from all panels, without having to write a loop for each panel? I know it's possible, but since I'm only a beginner I'm not able to figure this one out, even after hours of searching...
Thank you in advance! And if anything in my question is unclear please say so, so I can explain further!
This method may help. It loops through each control from a parent control, which in your case looks as tough it'd be Assignments_Panel, then for each control that belongs to the parent control, it will either loop through all child controls again, or disable the control, if it is a checkbox.
private void DisableCheckboxes(Control parentControl)
{
foreach (Control childControl in parentControl.Controls)
{
if (childControl is Panel childPanel)
{
DisableCheckboxes(childPanel);
}
else if (childControl is CheckBox childCheckBox)
{
childCheckBox.Enabled = false;
}
}
}
Well, we can enumerate all the controls within form while checking if the control is of type CheckBox; there are many implmentations for this, say
How to get ALL child controls of a Windows Forms form of a specific type (Button/Textbox)?
let's write good old Bread First Search (no Linq, recursion etc.)
private void LockChecked_Click(object sender, EventArgs e) {
Queue<Control> agenda = new Queue<Control>(new [] { this });
while (agenda.Count > 0) {
Control control = agenda.Dequeue();
if (control is CheckBox cb && cb.Checked)
cb.Enabled = false;
foreach (Control child in control.Controls)
agenda.Enqueue(child);
}
}

How to clear TextBoxes nested inside a TabControl, TabPage and 2 Panels?

The picture below represents a plug-in I am building.
Yellow = tabControl1; Orange = tabPage1; Blue = Main Panel (mainPanel); Green = 3 different panels inside the main panel (panel1, panel2 and panel3); White = TextBoxes (that I want to clear); DarkBlue = CheckBoxes corresponsing to the green panels
I am trying to clear any text from the TextBoxes that contain text and reset CheckBoxes when checked, with a button click.
I researched online and tried to accomplish this by the following way but it doesn't seem to be the correct way to handle this problem.
foreach (Control a in tabControl1.Controls)
{
foreach(Control b in tabPage1.Controls)
{
foreach (Control c in mainPanel.Controls)
{
foreach (Control d in panel1.Controls)
{
if (d is TextBox)
{
d.Text = " ";
}
if (d is CheckBox)
{
((CheckBox)d).Checked = false;
}
}
}
}
}
I have only shown panel1 here but tried doing the same thing for panel2 and 3 as well.
What exactly am I doing wrong here? Any help would be greatly appreciated!
You just need a simple recursive method that iterates all controls inside all child containers of a specified parent container, mainPanel, here.
If a control is of type TextBox or CheckBox, set its Text or Checked property accordingly:
(Note that you can also pass tabPage1 to the method, or any other ancestor)
ClearControls(panel1);
// or
ClearControls(tabPage1);
private void ClearControls(Control parent)
{
if ((parent == null) || (!parent.HasChildren))
return;
foreach (var ctl in parent.Controls.OfType<Control>())
{
if (ctl is TextBox txt) {
txt.Clear();
}
if (ctl is CheckBox chk) {
chk.Checked = false;
}
else {
if (ctl.HasChildren) {
ClearControls(ctl);
}
}
}
}
If you want to clear the TextBoxes and ComboBoxes inside of panel1 then you only need to loop through panel1's controls to do it. To handle any panel, you could just write a ClearPanel(Panel) function.
private void ClearPanel(Panel panel)
{
foreach (var ctrl in panel.Controls)
{
if (ctrl is TextBox tb)
{
tb.Clear();
}
else if (ctrl is CheckBox chkBx)
{
chkBx.Checked = false;
}
}
}
private void ClearPanel1Button_Click(object sender, EventArgs e)
{
ClearPanel(panel1);
}
Iterating through the controls in tabControl1, tabPage1, etc, etc adds unnecessary overhead if you already have a reference to the Panel you're dealing with. What's more, if any of the controls in the outer loops have an empty Controls collection then the inner loops won't execute. I suspect this might be why your code isn't working.
Note that the above solution will not handle any TextBox or ComboBox that is inside another container inside panel1. So, if panel1 had a GroupBox inside it which contained TextBoxes or ComboBoxes, they wouldn't be cleared. See the recursive solution below to handle that situation.
EDIT: After re-reading your question I thought maybe you want to clear all TextBox and CheckBox controls on the Form.
If you're needing to clear every TextBox or CheckBox on the Form, you can do this with recursion.
private void Clear(Control ctrl)
{
if (ctrl is TextBox tb)
{
tb.Clear();
}
if (ctrl is CheckBox chkBx)
{
chkBx.Checked = false;
}
foreach (Control child in ctrl.Controls)
{
Clear(child);
}
}
private void ClearButton_Click(object sender, EventArgs e)
{
Clear(this);
}
You could pass any Control to Clear(Control), so if you only wanted to do the TextBoxes and ComboBoxes on tabPage1 you could call Clear(tabPage1). This will clear all the TextBoxes and ComboBoxes on tabPage1, even if they're in a Panel or GroupBox or some other container.

How can I clear all form controls of an MDI child?

I have a function that clears a non-MDI child form, but when I apply it to an MDI child it doesn't do anything. I've tried attacking this problem from a few different angles without any luck, was hoping stackoverflow could help!
I've tried the code shown, I've also attempted to reference the child of the parent of the current form (Which is circular I know).
public static void ResetAllControls(Control form)
{
foreach (Control control in form.Controls)
{
if (control is TextBox)
{
TextBox textBox = (TextBox)control;
textBox.Text = "";
}
if (control is ComboBox)
{
ComboBox comboBox = (ComboBox)control;
if (comboBox.Items.Count > 0)
comboBox.SelectedIndex = 0;
}
if (control is CheckBox)
{
CheckBox checkBox = (CheckBox)control;
checkBox.Checked = true;
}
if (control is ListBox)
{
ListBox listBox = (ListBox)control;
listBox.ClearSelected();
}
}
}
I expect that passing this would clear all form controls as it does with standard forms.
I'm pretty sure that you have some kind of container on this for (eg. Panel) and controls are on this panel. Form.Controls will give you only controls that lay directly on the form. So you will have to do it recurrently:
public static void ResetAllControls(Control parent)
{
foreach(var child in parent.Controls)
ResetAllControls(child);
if(parent is TextBox)
{
(parent as TextBox).Text = "";
return;
}
//and so on
}

How to change the properties of controls of a usercontrol at runtime in C#?

I am a novice to C#.
My application contains Main form and a few usercontrols.
I want the usercontrol named "uc_MainMenu" to be displayed in the panel named "panel2" inside the Main form when I start running the applicaiton.
uc_MainMenu obj_uc_MainMenu = new uc_MainMenu();
private void frmMain_Load(object sender, EventArgs e)
{
this.panel2.Controls.Add(obj_uc_MainMenu);
}
It works.
uc_MainMenu contains a few buttons: btnHeadmaster,btnTeacher,btnStudent,btnAttendance,btnExam and btnLogin.
Each of those buttons' click will bring the corresponding predefined usercontrols.
Here is my question.
I want to disable all the buttons except btnLogin when the form loads.
How can I do that?
I tried this way but it didn't work.
foreach (Control ctrl in panel2.Controls)
{
if (ctrl.GetType() == typeof(Button))
{
((Button)ctrl).Enabled = false;
}
}
I can change each button's enabled properties in the uc_MainMenu, but if so I will have to change them again whenever I switch the usercontrols. That's why I left their enabled property to true when I designed the usercontrols.
Try this:
foreach (Control ctrl in obj_uc_MainMenu.Controls)
{
if (ctrl.GetType() == typeof(Button) && ((Button)ctrl).Name != "btLogin")
{
((Button)ctrl).Enabled = false;
}
}
Notice that I changed panel2 by obj_uc_MainMenu.
Create a property inside user control :
public bool MyButtonEnabled
{
get
{
return anyButtonButNo_btLogin.Enabled;
}
set
{
foreach (Control ctrl in this.Controls)
{
if (ctrl.GetType() == typeof(Button) && ((Button)ctrl).Name != "btLogin")
{
((Button)ctrl).Enabled = value;
}
}
}
}
Now you can use this property anywhere that usercontrol used.
uc_MainMenu obj_uc_MainMenu = new uc_MainMenu();
private void frmMain_Load(object sender, EventArgs e)
{
this.panel2.Controls.Add(obj_uc_MainMenu);
///this property will access the button inside that user control
obj_uc_MainMenu.MyButtonEnabled=false;
}
If your buttons is inside the obj_uc_MainMenu, then you can not retrieve it via panels.Controls. If you want to retrieve them, you should use obj_uc_MainMenu.Controls.
I don't know how did you define the user control obj_uc_MainMenu, then I guest you can do something like this:
foreach (Control ctrl in obj_uc_MainMenu.Controls)
{
if (ctrl.GetType() == typeof(Button))
{
((Button)ctrl).Enabled = false;
}
}
Find will find the panel. If it exists, then iterate through the usercontrol for type button and modify the button/s properties. No need of casting for button within foreach loop (we know its of type Button).
// Get the panel
var panel2 = Controls.Find("YourPanel", true).FirstOrDefault() as Panel;
// If it exists
if (panel2 != null)
{
foreach (var button in panel2.obj_uc_MainMenu.Controls.OfType<Button>())
{
// Set the value of each one
button.Enabled = false;
}
}

Changing a tab and clearing content

I have a program which gives two options through which to test a student's knowledge of complex numbers. However, I want the content in the tab (labels, textboxes) to be cleared when the tab is changed. Is there a method I can use to do this?
just handle the SelectedIndexChanged event of TabControl and retrieve all the controls within the tab. Now you can loop through controls and do whatever you want with them, like this-
// SelectedIndexChange Event
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
// Get Selected Tab
var selectedTab = tabControl1.SelectedTab;
foreach (Control ctrl in selectedTab.Controls)
{
if (ctrl is TextBox)
{
(ctrl as TextBox).Text = string.Empty;
}
if (ctrl is Label)
{
(ctrl as Label).Text = string.Empty;
}
// Other Controls....
}
}
hope it helps...!!
You could reset the value of label and textbox in Tabchange event. Take a look at
Tab Change MSDN
Hope it helps

Categories