I am trying to write a code which will uncheck all checkBoxes in my form when a button is clicked. I know that I could do
checkBox1.Checked = false;
checkBox2.Checked = false;
checkBox3.Checked = false;
and so on, but I have about 35 checkBoxes, so I was hoping to use a simpler code. I keep finding stuff online that looks like this;
foreach (Control cBox in this.Controls)
{
if (cBox is CheckBox)
{
((CheckBox)cBox).Checked = false;
}
}
And I was hoping to use something like that, instead of writing checkBox1.Checked = false; about 70 times (because I have 2 buttons, both of which need to do various things and then uncheck all the boxes.
I saw another solution that involved a Stack Panel or some type of code that looked more like Javascript or HTML than C#, and also seemed to involved writing out each checkBox.Checked status as its own line, which doesn't save me any lines of code.
Any tips would be appreciated. Thanks all :)
Answering my own question with some info from my new pal #HandbagCrab:
foreach (Control cBox in tabPage1.Controls)
{
if (cBox is CheckBox)
{
((CheckBox)cBox).Checked = false;
}
}
Adding the tabPage1 fixed my issue. Before, I had been using this.Controls which limited access to controls only within that dependency. I was still able to control other things based on the checkBoxes by naming them individually like checkBox1.Checked = false;, but this was only because I called to them by name, rather than asking the code to look through all Controls.
You can use C# 7.0+ pattern matching:
foreach(Control control in controls)
{
if (control is CheckBox chk) chk.Checked = false;
}
Related
foreach (Control c in this.Controls)
{
if (c is TextBox && c.Text.Length==0)
{
// [Associatedlabel].ForeColor = System.Drawing.Color.Red;
err = true;
}
instead of [Associatedlabel], I want to associate each textbox to label, so eventually all labels near the textbox that are empty will be red, how it can be done?
Thanks.
There is no fantastic way to find the label control back from the textbox. Using the form's GetChildAtPoint() method is something you can make easily work but are going to regret some day. Naming helps, like FooBarLabel matches FooBarTextBox. Now you can simply use the Controls collection to find the label back:
var label = (Label)this.Controls[box.Name.Replace("TextBox", "Label")];
But Winforms solves many problems by simple inheritance. Add a new class to your project and paste this code:
using System;
using System.Windows.Forms;
class LabeledTextBox : TextBox {
public Label Label { get; set; }
}
Compile and drop the new control from the top of the toolbox. Set the Label property in the designer, just pick it from the dropdown list. Boomshakalaka.
You can first manually set your TextBox's Tag property to these labels. Tag is meant to contain user-defined data, so you can place any object there. Then you can do simply:
foreach (Control c in this.Controls)
{
if (c is TextBox && c.Text.Length==0 && c.Tag is Label)
{
((Label)c.Tag).ForeColor = System.Drawing.Color.Red;
err = true;
}
}
This is the simplest solution, but a few more sophisticated exists though.
Creating a custom composite control consisting of a label, textbox and custom behavior;
Creating a control deriving from a textbox, which stores information about label it is connected with (as Hans Passant suggests)
Creating a Dictionary<TextBox, Label> or Dictionary<Control, Label>, which allows resolving such matters in runtime (variation on Steve's idea).
I suppose that you are using WinForms. In this environment you don't have any built-in functionality that associate a label to a textbox. So you need to build your own association.
This could be done creating a dictionary in the constructor of your code
public class MyForm : Form
{
private Dictionary<string, Label> assoc = new Dictionary<string, Label>();
public MyForm()
{
// Key=Name of the TextBox, Value=Label associated with that textbox
assoc.Add("textbox1", Label1);
assoc.Add("textbox2", Label2);
assoc.Add("textbox3", Label3);
}
}
.....
foreach (TextBox t in this.Controls.OfType<TextBox>())
{
if(t.Text.Length == 0)
{
assoc[t.Name].ForeColor = System.Drawing.Color.Red;
err = true;
}
else
assoc[t.Name].ForeColor = ??? system forecolor ???
}
I've got a problem with adding some controls into a Panel(which gets "PopUpped" by a ModalPopupExtender) and add a CheckedChanged-EventHandler.
First of all, when user clicks on a button, this happens inside the CreatePanelChoose() function:
foreach (ListItem item in lbSupplier.Items)
{
string cbid = "cb" + i;
CheckBox cb = new CheckBox();
cb.ID = cbid;
cb.Text = item.Text;
cb.AutoPostBack = true;
AjaxControlToolkit.MutuallyExclusiveCheckBoxExtender mecbe = new AjaxControlToolkit.MutuallyExclusiveCheckBoxExtender();
mecbe.ID = "mecbe" + cbid;
mecbe.TargetControlID = cbid;
mecbe.Key = "SupplierKEY";
mecbe.BehaviorID = mecbe.ID + i;
//Also adding a Label
phModalPopupExtender.Controls.Add(new LiteralControl("</br>")); //phModalPopupExtender is a PlaceHolder
phModalPopupExtender.Controls.Add(cb);
phModalPopupExtender.Controls.Add(mecbe);
phModalPopupExtender.Controls.Add(lbl);
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = cbid;
trigger.EventName = "CheckedChanged";
UpdatePanelMatrix.Triggers.Add(trigger);
i++;
ButtonOK.Enabled = false;
}
lblText.Text = "Select one Supplier";
ModalPopupExtender1.Show();
Then i add the EventHandler in the Page_LoadComplete:
As you can see it also gets asigned to the control (I think).
The ModalPopup shows up correctly, but if I click one of the CheckBox, then it just closes it without going into cb_CheckedChanged, but it makes a Async postback ...
If I check Request.Form["__ASYNCPOST"] its true and Request.Form["__EVENTTARGET"] is also correct. (It gives me the unique id!)
Request.Form["__EVENTARGUMENT"] is empty.
I think I also need to say that I use a masterpage.
The problem shouldn't be the lifecycle of the page, because msdn says:
LoadComplete
Raised at the end of the event-handling stage.
Use this event for tasks that require that all other controls on the page be loaded.
Its the onliest place it makes me think it would be right.
Btw: yes i looked trough the topics here allready, but nothing helped me ... (google fo sure also)
Edit 1:
if (IsPostBack)
{
if (recreating == true)
{
CreatePanelChoose();
}
}
In CreatePanelChoose i do the foreach now everytime when its a postback! But it still doesnt fire cb_ChangedChecked ...
Edit 2:
MSDN-Page-Lifecycle also says:
PreInit
Raised after the start stage is complete and before the initialization
stage begins.
Use this event for the following:
Create or re-create dynamic controls.
So i tried to recreate the Panel there. But i dont have the ListItems there to get the values ... ?!
Okay, gave up ...
If someone would still have an answer, it would be great!
Right now I dont use the OnCheckedChanged-Event of the CheckBoxes anymore.
I just let them select a CheckBox and on the OnClick of the ButtonOk I loop through the CheckBoxes and check which one is selected.
I'm new to tinkering with C#, and so far that's the extent of it. I'm just tinkering for a small project I have.
The redundancy is driving me crazy, though. Writing long lists of similar code taking up line after line just doesn't sit well with me.
I have a few tabs with checkboxes and radio buttons in them, that's where I noticed the duplication the most. Unfortunately I... don't quite grasp every aspect of C# as well as I should, yet. So I was hoping to learn from you folks.
Example:
//setup checkbox
checkBox1.AutoSize = true;
checkBox1.Checked = false;
checkBox1.CheckState = CheckState.Unchecked;
checkBox1.Location = new Point(5, 102);
checkBox1.Text = "Check Box 1!";
checkBox1.UseVisualStyleBackColor = true;
//set radio 1
radio1.AutoSize = true;
radio1.Checked = true;
radio1.Location = new Point(5, 33);
radio1.Size = new Size(20, 20);
radio1.Text = "Radio-e-o-e-o";
radio1.UseVisualStyleBackColor = true;
//set radio 2
radio2.AutoSize = true;
radio2.Checked = false;
radio2.Location = new Point(5, 56);
radio2.Size = new Size(18, 20);
radio2.Text = "Option 2!";
radio2.UseVisualStyleBackColor = true;
My instinct would be to set up some arrays with the variable data for things like the names and the distinct data. But as I said, I'm very new, I've only been tinkering... and the resources I've come across tend to either not match what I'm looking for, or add layers of complexity I'm probably not ready for.
If I got your question right: you can make a method:
private CheckBox DoSomethingWith(CheckBox checkBox, Point location, string text)
{
checkBox.AutoSize = true;
checkBox.Checked = false;
checkBox.CheckState = CheckState.Unchecked;
checkBox.Location = location;
checkBox.Text = text;
checkBox.UseVisualStyleBackColor = true;
return checkBox;
}
then pass a checkbox to it checkBox1 = DoSomethingWith(checkBox1, new Point(10,10), "My Text");
You can make your own class that inherits from RadioButton, set your default settings, and use it.
public class MyRadioButton : public RadioButton
{
MyRadioButton()
{
UseVisualStyleBackColor = true;
AutoSize = true;
}
}
Then you just add this control instead of RadioButton.
So...you want to refactor the Form1.designer.cs file?
Anything you do to "clean up" would place an unnecessary burden on the CPU just for the sake of "clean code". Just let the designer be (unless you're talking repeat designs, in which case a user control may be the way to go).
Those are my impressions on this, anyways
If all you're trying to do is tinker, and not set up a whole application architecture, and you're writing this yourself rather than trying to mess w/ the designer-generated code, then using some kind of structure you can loop over is probably you're best option. LINQ has some really nicer operators for doing simple transformations like that.
For example,
var formElements = myArrayofElementInfo.Select(e => CheckBox(e.Point, e.Text))
That also assumes you're using something like the CheckBox method presented by #Sean87 to consolidate construction.
Maybe you could reduce the redundancy by creating methods to initialize your controls passing the controls as parameters (you could also create the control inside the method itself). For example:
public void setupCheckbox (Checkbox checkbox, boolean autoSize, boolean checked, etc.)
public void setupRadioButton (RadioButton radiobutton, boolean autoSize, boolean checked, etc.)
And then create the controls using the above methods:
setupCheckbox (checkBox1, true, false, etc.)
setupRadioButton (radio1, true, false, etc)
setupRadioButton (radio2, true, false, etc)
Anyhow, the visual attributes of the classes you are referring to normally are defined within the IDE (e.g. Visual Studio) so normally you don't care about them. Maybe you could consider storing the Text in an array for the initialization of the different controls if you find it useful.
I want to change the property Background of many Buttons in WP7.
Can I write something like this:
Foreach (var item in (this.Content as Panel).Children)
{
If (Element is Button)
{
Element.Background = Color.red;
}
}
But this doesen't work,
Element.Background doesen't exist...
Anyone know how to fix it???
try this
//to be on the safe side first check
if(this.Content == null || !(this.Content is Panel)
return;
foreach (var item in (this.Content as Panel).Children)
{
if (item is Button)
{
Button b = item as Button;
b.Background = new SolidColorBrush(Colors.Red);
}
}
Can you try it with
Element.BackColor = Color.Red
instead of
Element.Background = Color.Red
Instead of looping through the controls, try binding their BackColor properties to something, be it a class that implements INotifyPropertyChanged with a property that returns a SolidColorBrush, another control's BackColor property, or whatever you choose to bind to. This can be done in silverlight without having to loop through the controls. Let the system manage the control appearance instead of writing it yourself.
Suppose I don't want to use
if (string.IsNullOrEmpty(textbox1.Text))
{
textbox1.Text = null;
}
for every textbox controls in form, is there a easier way to do it ?
Simple way is Loop through every control, see the below code
foreach (Control C in this.Controls)
{
if (C is TextBox)
{
if (C.Text == "")
{
C.Text = null;
}
}
}
It is one more way
foreach(Control txt in this.Controls)
{
if(txt.GetType() == typeof(TextBox))
if(string.IsNullOrEmpty(txt.Text))
txt.Text = null;
}
Hope it helps
You can iterate through the ControlCollection of the given form, e.g. frmMain.Controls
Now this will be the basic Control object, so you would need a test to see if it is of type TextBox.
.NET 2.0 - you'll have to check this manually
.NET 3.0+ - use the .OfType<TextBox> extension method to give you only a list of IEnumerable<TextBox>
Note that iterating through this from the form will only give you text boxes on that form. If you bind text boxes to a container it won't show up there.
Safest bet would be to write a recursive function that walks through all the control collections and passes the reference to your test function to perform your test and update.
Try this:
foreach(Control c in this.Controls)
{
if (c.GetType().FullName == "System.Windows.Forms.TextBox")
{
TextBox t = (TextBox)c;
t.Clear();
}
}
You can create a derived control from textbox control, and override its text property.