I want to simplify this code. The Code should put all panels (panel1 - panel10) into an panel array
A solution could be with a for loop, but I don't know how to increase the panelname:
public Form1()
{
InitializeComponent();
Panel[] arr = new Panel[10];
int i = 0;
arr[i] = panel1;
arr[i++] = panel2;
arr[i++] = panel3;
arr[i++] = panel4;
arr[i++] = panel5;
arr[i++] = panel6;
arr[i++] = panel7;
arr[i++] = panel8;
arr[i++] = panel9;
arr[i++] = panel10;
}
Panel[] panel = new Panel []
{
panel1,
panel2,
panel3,
...
panel10,
};
if panel1..panel10 are directly on the form you can try Linq:
using System.Linq;
using System.Text.RegularExpressions;
...
public Form1() {
InitializeComponent();
// If you want all the panels, remove (comment out) "Where"
Panel[] arr = Controls
.OfType<Panel>()
.Where(panel => Regex.IsMatch(panel.Name, "^panel([0-9]|(10))$"))
.ToArray();
}
Edit: If you have, say, 42 panels the only thing you have to change is the filter Where:
public Form1() {
InitializeComponent();
Panel[] arr = Controls
.OfType<Panel>()
.Where(panel => {
// Given a panel you have to decide should you add it to array or not
var match = Regex.Match(panel.Name, "^panel(?<num>[0-9]+)$");
return match.Success &&
int.Parse(match.Groups["num"].Value) >= 0 &&
int.Parse(match.Groups["num"].Value) <= 42; })
.ToArray();
}
In case you want to organize all the panels with Name like panelNumber (e.g. panel2, panel17, panel347...) you can simplify the Where into
.Where(panel => Regex.IsMatch(panel.Name, "^panel[0-9]+$"))
Create the array with contents like this:
public Form1()
{
InitializeComponent();
Panel[] arr = new Panel[]{
panel1,
panel2,
panel3,
panel4,
panel5,
panel6,
panel7,
panel8,
panel9,
panel10
};
}
An other solution is to use reflection like:
Panel[] arr = new Panel[10];
const string PanelName = "panel";
for (int i = 0; i < arr.Length; i++)
{
FieldInfo pi = GetType().GetField(PanelName + (i + 1),
BindingFlags.NonPublic | BindingFlags.Instance);
arr[i] = ((Panel)pi.GetValue(this));
}
Note that this is just an example. If a panel is not available this code will crash due to a null returned. If this could be possible, you need to improve the code a little bit.
Why don't you try Linq? Assuming all the panels are in the form.
var panelArr = Controls.OfType<Panel>(); //Filtering based on Type
panelArr.Where(p=> Regex.IsMatch(p.Name, "^panel([0-9]|(10))$")) //Filtering based on Panel Name
panelArr.ToArray(); //Fianlly into Array
You can set name panel.Name = "pnl" + i.ToString();
public Form1()
{
InitializeComponent();
Panel[] arr = new Panel[10];
for (int i = 0; i < arr.Length; i++)
{
Panel panel = new Panel();
panel.Name = "pnl" + i.ToString();
arr[i] = panel;
}
}
Related
I've currently got 5 labels in a Windows Form on Visual Studio and I need to populate an array with these 5 labels.
The 5 labels are named 'die1', 'die2', 'die3', 'die4', 'die5'
I figured I should be able to generate the array and then use a for loop to populate it, but the for loop is where I get stuck. This is what I have so far:
Label[] labels = new Label[5];
for (int i = 0; i < labels.Length; i++)
labels[i] = new Label(die(i));
Any help would be appreciated!
You can use LINQ to search the collection of controls on the Form, and create an array from any Label's whose name starts with "die":
var labels = Controls.OfType<Label>()
.Where(label => label.Name.StartsWith("die"))
.ToArray();
Label[] lbl ;
private void setupControls()
{
int Totallbl = 5;
int height = 30;
lbl = new Label[Totallbl];
try
{
for (int i = 0; i < Totallbl; i++)
{
lbl[i] = new Label();
lbl[i].Location = new Point(20, ((i + 1) * height));
lbl[i].Name = "lbl" + i;
lbl[i].Text = "LabelText";
lbl[i].AutoSize = true;
this.Controls.Add(lbl[i]);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
You can call back the label like this:
lbl[0].Text = "Text u want to change"
lbl[1].Text = "Text u want to change"
...
string[] board = new string[9];
for (var i = 0; i < 9; i++)
{
board[i] = (textBox1.Text);
}
I'm trying to make a loop which puts the text of textboxes in the array, but I can't figure out how to put the i variable in the 'textBox.Text' statement. I've tried this:
board[i] = ("textBox" + i + ".Text");
But this returns 'textBox1.Text'. How do I make the textbox.Text statement 'compatible' with the for loop?
You didn't tell us what API are you using as #Jeppe Stig Nielsen commented.
Asp.net? WPF? Windows Forms?
In Asp.net you can use FindControl method
string[] board = new string[9];
for (var i = 0; i < 9; i++)
{
board[i] = ((TextBox)FindControl("textBox" + i)).Text
}
In WPF you can use FindName method:
string[] board = new string[9];
for (var i = 0; i < 9; i++)
{
board[i] = ((TextBox)this.FindName("textBox" + i)).Text;
}
Use more meaningful control names if you want to maintain your code sometime. The business logic should not be dependent on control names.
However, if you want to get an array of all textboxes in a container control like the form you could also use LINQ:
string[] board = this.Controls.OfType<TextBox>()
.Where(txt => txt.Name.StartsWith("textBox"))
.Select(txt => txt.Text)
.ToArray();
If you only want to take textboxes from 1-9:
var txtNames = Enumerable.Range(1, 9).Select(i => "textBox" + i);
string[] board = this.Controls.OfType<TextBox>()
.Where(txt => txtNames.Contains(txt.Name))
.Select(txt => txt.Text)
.ToArray();
Try this ,
string[] arr= new String[3];
for (int i = 0; i <= 2; i++)
{
TextBox testTextBox = (TextBox)this.Controls["textBox" + i.ToString()];
arr[i] = testTextBox.Text;
}
Suppose I have this in page load:
Label lblc = new Label();
for (int i = 1; i <= 10; i++)
{
lblc.Text = i.ToString();
this.Controls.Add(lblc);
}
How can I manipulate each of these controls at run time?
I want to:
Set/get their text.
Reference a particular control, in this case Label.
Use an array if you know how many labels you will have,
Label[] lblc = new Label[10];
for (int i = 0; i < 10; i++)
{
lblc[i] = new Label() { Text = (i + 1).ToString() };
this.Controls.Add(lblc[i]);
}
Then you will reference the textbox 1 with lblc[0] and textbox 2 with lblc[1] and so on. Alternatively if you do not know how many labels you will have you can always use something like this.
List<Label> lblc = new List<Label>();
for (int i = 0; i < 10; i++)
{
lblc.Add(new Label() { Text = (i + 1).ToString() });
this.Controls.Add(lblc[i]);
}
You reference it the same way as the array just make sure you declare the List or the array outside your method so you have scope throughout your program.
Suppose you want to do TextBoxes as well as Labels well then to track all your controls you can do it through the same list, take this example where each Label has its own pet TextBox
List<Control> controlList = new List<Control>();
for (int i = 0; i < 10; i++)
{
control.Add(new Label() { Text = control.Count.ToString() });
this.Controls.Add(control[control.Count - 1]);
control.Add(new TextBox() { Text = control.Count.ToString() });
this.Controls.Add(control[control.Count - 1]);
}
Good luck! Anything else that needs to be added just ask.
Your code creates only one control. Because, label object creation is in outside the loop. you can use like follows,
for (int i = 1; i <= 10; i++)
{
Label lblc = new Label();
lblc.Text = i.ToString();
lblc.Name = "Test" + i.ToString(); //Name used to differentiate the control from others.
this.Controls.Add(lblc);
}
//To Enumerate added controls
foreach(Label lbl in this.Controls.OfType<Label>())
{
.....
.....
}
Better to set the Name and then use that to distinguese between the controls
for (int i = 1; i <= 10; i++)
{
Label lblc = new Label();
lblc.Name = "lbl_"+i.ToString();
lblc.Text = i.ToString();
this.Controls.Add(lblc);
}
when:
public void SetTextOnControlName(string name, string newText)
{
var ctrl = Controls.First(c => c.Name == name);
ctrl.Text = newTExt;
}
Usage:
SetTextOnControlName("lbl_2", "yeah :D new text is awsome");
I have 100 files in Resources named "1.png", "2.png". I have a PictureBox[] array generated with code, and I want to set array[i].Image = string.Format("Properties.Resources.{0}.png", i); But this does not work.
What is the best way to do this?
If your images have names that conform to some pattern inside the resource file (like "Image1", "Image2", etc.), you may load them by their names:
ResourceManager rm = Resources.ResourceManager;
array[i].Image = (Bitmap)rm.GetObject(string.Format("Image{0}", i));
You need to use Reflection, Something like following would do the task:
var properties = typeof(Properties.Resources).GetProperties
(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
PictureBox[] array = new PictureBox[100];
int counter = 0;
foreach (PropertyInfo property in properties)
{
var image = property.GetValue(null, null) as System.Drawing.Bitmap;
if (image != null && counter < array.Length)
{
array[counter] = new PictureBox();
array[counter++].Image = image;
}
}
Remember to include using System.Reflection; at the top.
you can refer to this post.
or you can simply use :
array[i].Image = Properties.Resources.img1
namespace your_name_project
{
public partial class Form_Begin : Form
{
PictureBox[] pictureBoxs = new PictureBox[6];
public Form_Begin()
{
InitializeComponent();
pictureBoxs[0] = pictureBox1; pictureBoxs[1] = pictureBox2; pictureBoxs[2] = pictureBox3;
pictureBoxs[3] = pictureBox4; pictureBoxs[4] = pictureBox5; pictureBoxs[5] = pictureBox6;
}
//continue
List<PictureBox> pictureBoxes = new List<PictureBox>();
private void buttonX1_Click(object sender, EventArgs e)
{
for (int i = 0; i <3; i++)
{
pictureBoxs[i].Image =your_name_project.Properties.Resources.image_1;// load image1 and Image_2from resource in property of picturebox
}
for (int i = 3; i < 6; i++)
{
pictureBoxs[i].Image = your_name_project.Properties.Resources.Image_2;
}
}
}
}
Hey!
I want to create an array of fields. however my code return an error of the following: Field 'WindowsFormsApplication1.Form1.fieldArray' is never assigned to, and will always have its default value null.
any suggestion to how I can solve this error?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Field[] fieldArray;
private Field f;
public Form1()
{
InitializeComponent();
}
private void populateTree(string path, TreeNode tv1)
{
string[] dir = Directory.GetDirectories(path);
foreach (string d in dir)
{
string entry = Path.GetFileName(d);
TreeNode t = tv1.Nodes.Add("Folder", entry, 0);
populateTree(d, t);
}
string[] files = Directory.GetFiles(path);
foreach (string f in files)
{
string entry = Path.GetFileName(f);
tv1.Nodes.Add(f, entry, 1);
}
}
private void Form1_Load(object sender, EventArgs e)
{
//populate the tree
TreeNode t = treeView1.Nodes.Add("Units");
populateTree(#"..\units\", t);
f = new Field();
for (int i = 0; i < 10; i++)
{
fieldArray[i] = new Field();
}
fieldArray[1].label.AutoSize = true;
fieldArray[1].label.Location = new System.Drawing.Point(323, 9);
fieldArray[1].label.Name = "Programtittle";
fieldArray[1].label.Text = "UAI UnitDef Editor";
this.Controls.Add(fieldArray[1].label);
int clabel = 36;
//fieldArray[1].varName = new string[] { "unitName", "name", "description" }; //define labels
//popluate label
for (int i = 1; i < fieldArray[i].varName.Length; i++)
{
fieldArray[i].label = new Label();
fieldArray[i].label.AutoSize = true;
fieldArray[i].label.Location = new System.Drawing.Point(323, clabel);
fieldArray[i].label.Name = "label";
this.Controls.Add(fieldArray[i].label);
fieldArray[i].label.Text = fieldArray[i].varName[i];
clabel = clabel + 26;
}
//populate textbox
int cbox = 33;
for (int i = 0; i < fieldArray[i].varName.Length; i++)
{
fieldArray[i].txtBox = new TextBox();
fieldArray[i].txtBox.Location = new System.Drawing.Point(380, cbox);
fieldArray[i].txtBox.Name = "txtBox";
fieldArray[i].txtBox.Size = new System.Drawing.Size(100, 50);
this.Controls.Add(fieldArray[i].txtBox);
cbox = cbox + 26;
}
}
private void populateLabelTxtBox(string path)
{
//f.txtBox.Multiline = true; //added for testing purpose;
//read,split file
string text = System.IO.File.ReadAllText(path);
char[] delimiters = new char[] { '{', '=', ';', '}' };
string[] parts = text.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < parts.Length; i++)
{
fieldArray[i].txtBox.Text = parts[i];
}
}
private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (treeView1.SelectedNode.Name != "Folder")
{
string text = System.IO.File.ReadAllText(treeView1.SelectedNode.Name);
//f.txtBox.Text = text;
populateLabelTxtBox(treeView1.SelectedNode.Name);
}
}
}
}
A list might be easier than an array, but: you are assigning items to a null array; once you know the number you need, create the array first:
fieldArray = new Field[10];
for (int i = 0; i < 10; i++)
{...}
However, personally I'd use a list:
private readonly List<Field> fields = new List<Field>();
...
fields.Add(someField);
You never initialize fieldArray
//Change
private Field[] fieldArray;
to
private Field[] fieldArray = new Field[10];
You never initialized fieldArray. Something like fieldArray = new Field[10]; in the constructor of your Form should do it.
Before you try to access elements in the fieldArray you have to initialize the array like so:
fieldArray = new Field[/*size of the array*/];
However, be careful to create an array large enough to store all your fields. Suppose you create a Field[5] array of 5 elements, and you try to assign a value to fieldArray[5] you will get an OutOfBounds exception.
Before doing your loop where you initialize each element of the array, you need to initialize the array itself:
fieldArray = new Field[10]; // Create this with the appropriate size
for (int i = 0; i < 10; i++)
{
fieldArray[i] = new Field();
}
On a different note, you're never actually setting fieldArray[0] - I suspect your code that is explicitly setting fieldArray[1].XXX should be working on element 0.
Initialize your array when you declare it:
private Field[] fieldArray = new Field[100]; // size == 100
I don't see any line that assigns the array: like
int number_of_elements = 100;
fieldArray = new Field[number_of_elements];
if the number of fields is dynamic I would use an ArrayList, like
List fieldArray = new List();
and then add elements to it:
fieldArray.Add(...)
You must initialize your array
fieldArray = new Field[10];
fieldArray[i] = new Field();
The above code makes you think that the array is already initialized, but actually it has not. You need to have something like the following to allocate some memory for the array.
fieldArray = new Field[/*length or size*/];