Concatenate strings to make Picturebox name - c#

i have lot of pictureboxes named this way: PBr1_1, PBr1_2, ... PBr1_9
I'd like to make loop
for (int i = 0; i < 10; i++)
{
if (Textbox.Text[i].ToString() == "1"){ "PBr1_"+"i".Tag = "cb.png";}
}
so for i=0 => PBr1_0, i=10 => Pbr1_10.
Example i have value in textbox: 0001011101 - then if value in textbox is "1" then i'd like to change picturebox tag.
How to automate this process, using for example loop "for"?

I suppose your controls are on a WinForm (this) and the ones with that name are all pictureboxes.
If so, that's the way ----
for (int i = 0; i < 10; i++)
{
if (Textbox.Text[i].ToString() == "1")
{
Control[] c = this.Controls.Find("PBr1_" + i.ToString(), true);
if(c != null && c.Length > 0) c[0].Tag = "cb.png";
}
}

You can put the picture boxes in to a List<PicutreBox> and iterate over the list.
var pictures = new List<PictureBox>();
pictures.Add(pic1);
pictures.Add(pic2);
//...
for (int i = 0; i < 10; i++)
{
if (Textbox.Text[i].ToString() == "1")
pictures[i].Tag = "cb.png";
}
Dynamic variable names as in your example are not supported.

Create an array (or list) that contain the picture boxes and use those within the for loop.
You can also use reflection but in my opinion it is best not to use that in this case.

If you are using WinForm you can use Control.Find method to locate a control by name
Once you have got the control you can easily change any property

Related

Fill an array with a loop

I want to get a shorter code than now but I don't know how.
What I do now is like the code below.
arrPictureBox[0] = picChair0;
arrPictureBox[1] = picChair1;
arrPictureBox[2] = picChair2;
arrPictureBox[3] = picChair3;
arrPictureBox[4] = picChair4;
arrPictureBox[5] = picChair5;
arrPictureBox[6] = picChair6;
arrPictureBox[7] = picChair7;
arrPictureBox[8] = picChair8;
arrPictureBox[9] = picChair9;
arrPictureBox[10] = picChair10;
arrPictureBox[11] = picChair11;
(pic) is a picturebox.
But I want less code but I don't know if it possible to do this with a loop (for loop).
for (int i = 0 ; i < arrPictureBox.Length; i++)
{
arrPictureBox[i] = picChair + i;
}
If picChairN is a local variable then there's nothing you can do to simplify it as much as you'd like. The best you can do is
arrPictureBox = new [] { picChair0, picChair1, picChair2, picChair3,
picChair4, picChair5, picChair6, picChair7,
picChair8, picChair9, picChair10, picChair11};
If picChairN is a class member (e.g. a field created by the designer) then you could use reflection, but considering you already have the array method typed out I don't see much benefit.
Let's predict you're on WinForms and the pictureBoxes already exist, then you can use the following:
for (int i = 0; i < arrPictureBox.Length; i++)
{
arrPictureBox[i] = this.Controls["picChair" + i];
}
Which actually does this:
get the first Control (a PictureBox for example) with the given name
add the found control to the array of pictureboxes
EDIT:
It might be useful to check for non existing pictureBoxes:
for (int i = 0 ; i < arrPictureBox.Length; i++)
{
var pb = this.Controls["picChair" + i] as PictureBox;
if (pb != null)
{
arrPictureBox[i] = pb;
}
}
You can use al List like below.
List<string> arrPictureBox = new List<string>();
for (int i = 0; i < 20; i++)
{
arrPictureBox.Add("picChair" + i);
}
var result = arrPictureBox.ToArray();
Hope it helps.
If all the picture boxes are on the same form and are the ONLY picture boxes on the form, you can loop through them with something like the following:
int x = 0;
foreach(Control c in this.Controls)
{
if(c is PictureBox)
{
arrPictureBox[x++] = c
}
}

Use loop to clear. textBox[i].Clear(). Is this possible?

I am just looking to know this to try and clean up my code, and also for future reference.
I have a number of textBoxes.
tbPart1.Clear();
tbPart2.Clear();
tbPart3.Clear();
tbPart4.Clear();
tbPart5.Clear();
tbPart6.Clear();
tbPart7.Clear();
Is there any way I could use a loop to replace the numbers?
I tried this, but have no idea how i could run the string.
for (int i = 1; i == 7; i++)
{
string p = "tbPart" + i.ToString() + ".Clear";
}
Inside of the form's code (i.e. in a button click event handler), you can enumerate through all of the TextBox controls on the form and perform a specific action on them:
this.Controls.OfType<TextBox>().ToList().ForEach(x => x.Clear());
If you need to only clear some of the TextBox controls, you can provide a sort of filter like so:
this.Controls.OfType<TextBox>()
// Add a condition to clear only some of the text boxes - i.e. those named "tbPart..."
.Where(x=>x.Name.StartsWith("tbPart"))
.ToList().ForEach(x => x.Clear());
No, you cannot do it that way. But you can define an array or list where you put the controls and then clear them. For example:
List<TextBox> textboxes = new List<TextBox>();
textboxes.Add(tbPart1);
textboxes.Add(tbPart2);
textboxes.Add(tbPart3);
...
Then when you want to clear them
foreach (var tb in textboxes)
tb.Clear();
TextBox[] boxes = new [] {
tbPart1,
tbPart2,
tbPart3,
tbPart4,
tbPart5,
tbPart6,
tbPart7
};
for (int i = 0; i < boxes.Length; i++)
{
boxes[i].Clear();
}
i think you should use an array of textbox then you can do a loop depends the count of numbers of textboxes.
foreach(Control ctrl in this.Controls)
{
if(ctrl.GetType() == typeof(TextBox))
{
ctrl.Text = String.Empty;
}
}
Answer number one by using Control name inside panel1
private void button2_Click(object sender, EventArgs e)
{
string currentCtrlName;
for (int i = 0; i < panel1.Controls.Count; i++)
{
currentCtrlName = "textBox" + (i+1).ToString();
panel1.Controls[currentCtrlName].Text = "";
}
}
==================
Answer number one by using Control index as a child inside panel1
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < panel1.Controls.Count; i++)
{
panel1.Controls[i].Text = "";
}
}
==================

Checkbox name with For counter

I have this loop and multiple leds. The names of the leds are Led0, Led1, Led2 etc
Now i want to change the background of each Led with this loop so i use the counter iTeller.
I use WPF and only work in the mainwindow.
for (int iTeller = 0; iTeller < bits.Count(); iTeller++)
{
if (bits[iTeller] == 1)
{
//this doesn't work
*Led+iTeller+.Background = Brushes.Green;*
}
}
Try Like This (WPF)
for (int iTeller = 0; iTeller < bits.Count(); iTeller++)
{
if (bits[iTeller] == 1)
{
object i = this.FindName("Led" & iTeller);
if (i is CheckBox)
{
CheckBox k = (CheckBox)i;
MessageBox.Show(k.Name);
}
}
}
This will not work for a lot of reasons. The first is, that your leds are some type of control, which you need in a variable, you cannot simply call them like this.
Do you use WPF or Winforms?
You need a list of your leds, then you can iterate over the list and assign the value to each led
You cannot resolve a variable name like this, you can use the Find method (at least in Windows Forms), to find a named control.
You can also store the controls in an array, that way you prevent using relatively slow Find calls and other error checking:
var leds = new CheckBox[] { Led0, Led1, Led2, Led3, Led4, Led5, Led6, Led7 };
for (int iTeller = 0; iTeller < bits.Count(); iTeller++)
{
if (bits[iTeller] == 1)
{
leds[iTeller].Background = Brushes.Green;
}
}
This worked
for (int iTeller = 0; iTeller < bits.Count(); iTeller++)
{
if (bits[iTeller] == 1)
{
var myCheckbox = (CheckBox)this.FindName("Led" + iTeller);
myCheckbox.Background = Brushes.Green;
}
}
Thanks everyone

Reference a sequence of labels in C#

I have message box that asks the user whether they want to restart.
if (MessageBox.Show("Restart?",
"Restart and Clear",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
labels.Text="0"
}
Instead of "labels" I want to use label1, label2, label3, etc. all the way to label60. I could do label1.Text=label2.Text .... = 0 but that would take a while. Is there an easy way to do this, possibly using a for statement?
I believe what you are trying to do is reset every label's text to 0 if so
foreach(Label l in this.Controls.OfType<Label>())
l.Text = "0";
On a side note, you should try to give your controls meaningful names to help when maintaining your code
Edit
A more robust approach but to make sure you don't reset text that you don't wish to change you could make a subclass of label and then use this class for labels that can be reset
class ResettableLabel : Label
foreach(ResettableLabel l in this.Controls.OfType<ResettableLabel >())...
I'd say you could use Control.ControlCollection.Find
for (int i = 1; i <= 60; i++)
{
label = Controls.Find("label" + i.ToString()) as Label;
label.Text="0"
}
Not tested but I think this Linq version should do the same
Enumerable
.Range(1, 60)
.ToList()
.ForEach(i => (Controls.Find("label" + i.ToString()) as Label).Text = "0");
You could add all of your labels to a collection or a list. Then you could easily ForEach the list.
var allLabels = new List<Label>( { label1, label2, label3, ... , label60});
allLabels.ForEach(l=> l.Text = "0");
Yes, you could use reflection like this:
for (int i = 1; i <= 60; i++)
{
var fi = this.GetType().GetField(string.Format("label{0}", i));
if (fi == null) { continue; }
fi.SetValue(this, "0");
}
Another approach would be to use the Find method:
for (int i = 1; i <= 60; i++)
{
var c = this.Controls.Find(string.Format("label{0}", i), true);
if (c == null) { continue; }
((Label)c).Text = "0";
}
In short, there are a lot of ways to skin this cat. Out of the two I provided, the second is going to be more efficient and would probably be my choice.
Use reflection:
// using System.Reflection;
for (int i = 1; i <= 60; i++)
((Label)this.GetType().GetField("label" + i, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this)).Text = "0";

Array values into list box

I have the following code.
I am trying to insert values into a listbox, and then be able to resort the values by alphabetical order and re display them in the same listbox. For some reason code doesn't work (no errors - just when i push the button the listbox clears)
protected void sortButton_Click(object sender, ImageClickEventArgs e)
{
string[] movieArray = new string [cartListBox.Items.Count];
for (int i = 0; i < cartListBox.Items.Count; i++)
{
movieArray[i] = cartListBox.Items[i].ToString();
}
Array.Sort(movieArray);
cartListBox.Items.Clear();
for (int i = 0; i < cartListBox.Items.Count; i++)
{
cartListBox.Items.Add(movieArray[i].ToString());
}
}
I think problem is in last loop.
Do that like follows:
cartListBox.Items.Clear();
for (int i = 0; i < movieArray.Length; i++)
{
cartListBox.Items.Add(movieArray[i].ToString());
}
When you are clearing cartListBox.Items.Clear();, it should not be taken for loop counter like, for (int i = 0; i < cartListBox.Items.Count; i++)
cartListBox.Items.Count was creating problem.
You can avoid all that looping, and your bug, by doing this in a more modern way:
var items = cartListBox.Items
.Select(item => item.ToString())
.OrderBy(x => x);
cartListBox.Items.Clear();
cartListBox.Items.AddRange(items);
cartListBox.Items.Count // is 0 length
you are doing in the previous step:
cartListBox.Items.Clear();
To add movieArray to listbox use AddRange
carListBox.Items.AddRange(movieArray);
To sort just set sorted =true
carListBox.Sorted=true;
Complete code is below
carListBox.Items.AddRange(movieArray);
carListBox.Sorted=true;

Categories