I have a Panel and two LinkLabels added on the panel and a treeview.
now in the panel_Paint event i want that the linklabel colors become white and background color of treeview turns black.
how do i do this?
the below code works only when there is no tree view in the panel but when i add a treeview also in the panel then it says :
Unable to cast object of type 'System.Windows.Forms.TreeView' to type 'System.Windows.Forms.LinkLabel'.
foreach (LinkLabel link in panel1.Controls)
{
link.LinkColor = Color.White;
}
Your panel contains all the controls - one of them is a TreeView which cannot be cast into a LinkLabel. In your loop you need to check the type of the control like this:
foreach (Control control in panel1.Controls)
{
if (control is LinkLabel)
{
... set link color
}
else if (control is TreeView)
{
... set background
}
}
Alternatively if you only have one LinkLabel and one TreeView you would not need a loop - just access them by name like you did with panel1
Try this:
foreach (Control ctrl in panel1.Controls)
{
LinkLabel link = ctrl as LinkLabel;
if(link != null)
link.LinkColor = Color.White;
}
Your getting the error because your trying to cast all controls in panel1 to a LinkLabel. You need to try something like this
foreach (Control control in panel1.Controls)
{
if (control.GetType() == typeof(LinkLabel))
{
LinkLabel link = (LinkLabel)control;
link.LinkColor = Color.White;
}
}
Hope this helps.
Edit: I knew there was a method but wasn't sure 100% of the name or syntax. See below an improved answer.
foreach (LinkLabel link in panel1.Controls.OfType<LinkLabel>())
{
link.LinkColor = Color.White;
}
Hope this is better for you.
Related
I am trying to clear the images from all the picture boxes on a single click.
foreach (Control x in this.Controls)
{
if (x is PictureBox)
{
x.Image = null;
}
}
I am getting this error:
Thanks for the help.
Just use the Controls.OfType<> method so you get only PictureBoxes from the Form:
foreach(PictureBox pb in this.Controls.OfType<PictureBox>())
{
pb.Image = null;
}
It is obvious, Control class does not have a property with the name Image. You need to cast the control to a PictureBox object, like this:
foreach (Control control in this.Controls) // renamed x to control (with a small c), which enhances the readability
{
if (control is PictureBox pictureBox) // As #EtiennedeMartel suggested, this is a neat and efficient way of achieving the desired. Use this please.
{
pictureBox.Image = null;
}
}
I have a windows form which include some textbox and labels.In my program I set all of them unvisible and when I press button it makes all of the labels and textbox visible with the code below and it works perfect.
List<Label> lbls = this.Controls.OfType<Label>().ToList();
foreach (var lbl in lbls)
{
if (lbl.Name.StartsWith("label"))
{
lbl.Visible = true;
}
}
List<TextBox> txts = this.Controls.OfType<TextBox>().ToList();
foreach (var txt in txts)
{
if (txt.Name.StartsWith("textBox"))
{
txt.Visible = true;
}
}
But when I put all of my labels and textboxes into groupbox.My code doesn't work.How can I do this?
Note: My groupbox is also unvisible and when I press button.
groupBox1.visible =true;
This code works and groupbox panel seems, but the code of labels and textboxes doesn't work.
Because you are working with the immediate child of Form here
List<Label> lbls = this.Controls.OfType<Label>().ToList();
Notice this that means your current form. so when you have controls outside in form it works,
But when you put them inside group box it won't be the immediate child anymore.
so use
List<Label> lbls = groupBox1.Controls.OfType<Label>().ToList();
This will give you access to immediate children of the group box.
You're better off creating a recursive method of your own. Try implementing something like this:
private void MakeControlsInvisible(Control container, params Type[] controlTypes)
{
foreach (Control control in container.Controls)
{
if (controlTypes.Contains(control.GetType()))
{
control.Visible = false;
}
if (control.Controls.Count > 0)
{
MakeControlsInvisible(control, controlTypes);
}
}
}
And then using it on whatever container you wish:
MakeControlsInvisible(this, typeof(Label), typeof(TextBox)); // Will make all labels and textboxes inside the entire form invisible.
MakeControlsInvisible(groupBox1, typeof(Label), typeof(TextBox));// Will make all labels and textboxes inside groupBox1 invisible.
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 ???
}
When I create & add a control to my WinForm using the designer, is my control automatically added to a collection with all the others somewhere ?
Let's say there are like 20 TextBox and I need to clear them all at the same time without calling it like so :
txtbox1.Clear();
txtbox2.Clear();
txtbox3.Clear();
...
I know I should have created manually each control without the designer and add them in a collection but it's too late for that now. So any idea if I can access the whole group of controls ?
try this
private void ClearTextBoxes()
{
Action<Control.ControlCollection> func = null;
func = (controls) =>
{
foreach (Control control in controls)
if (control is TextBox)
(control as TextBox).Clear();
else
func(control.Controls);
};
func(Controls);
}
Oh I actually found out how to do this just after I wrote my question.
I can use a foreach loop on this.controls.
Then I test if the control is a TextBox.
foreach (Control x in this.Controls)
{
if (x is TextBox)
{
((TextBox)x).Text = String.Empty;
}
}
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.