for (int f = 1; f <= 6; f++)
{
textBox{f+11} = (loto[f].ToString());
}
Hi again,
I'm trying to learn c# on my own. Sorry for this noobish questions :)
To be more spesific, that's what I want :
A shortcut to write codes like that :
textBox12.Text = loto[1].ToString();
textBox11.Text = loto[2].ToString();
textBox10.Text = loto[3].ToString();
textBox9.Text = loto[4].ToString();
textBox8.Text = loto[5].ToString();
textBox7.Text = loto[6].ToString();
This code is working but i want to write it in a for loop
You can use a dictionary.
Dictionary<int, TextBox> dictionary = new Dictionary<int, TextBox>();
dictionary.Add(1, textbox1);
... // add the other textboxes
// access the dictionary via index
dictionary[f+11] = ...
You could use a List<TextBox> and initialise it in the constructor, after the call to InitialiseComponent() that you will see in the constructor.
Here's how:
Firstly add to your form class a List<TextBox> as follows:
private List<TextBox> textboxes = new List<TextBox>();
Then initialise the list in your constructor something like this (change Form1 to the name of your form's constructor):
public Form1()
{
// ...
InitializeComponent();
// ...
textboxes.Add(textBox1);
textboxes.Add(textBox2);
textboxes.Add(textBox3);
// ...etc up to however many text boxes you have.
}
Then when you want to access the textboxes, you can do so like this:
for (int f = 1; f <= 6; ++f)
{
textboxes[f+11].Text = loto[f].ToString(); // From your example.
}
I'm not sure if your TextBox controls are already on your form. If not and you wanted to create your TextBox controls dynamically, you could do something like this:
for (int f = 1; f <= 6; f++)
{
Dictionary<int, TextBox> dict = new Dictionary<int, TextBox>();
dict.Add(f, new TextBox());
dict[f].Location = new Point(0, f * 20);
dict[f].Text = loto[f].ToString();
this.Controls.Add(dict[f]);
}
You can't. You have to store them in a list of dictionary and access them this way. So
add controls to list/dictionary
in your for loop, access them by index
Related
I have done the following code and works well. I am wondering how I can do a for loop to clean this code from 38 lines into 2 lines.
s0s.Text = seg[0].start.ToString("X8");
s0e.Text = seg[0].end.ToString("X8");
s1s.Text = seg[1].start.ToString("X8");
s1e.Text = seg[1].end.ToString("X8");
// .. many more ..
s19s.Text = seg[19].start.ToString("X8");
s19e.Text = seg[19].end.ToString("X8");
I can obviously do the seg[i] substitution, but how do i do it with the text boxes?
I suppose you could use the Controls property and call OfType<T>() to get all the instances of TextBoxes in your Form instance
Filters the elements of an IEnumerable based on a specified type.
Then convert the results to a Dictionary based on the control Name
// this could potentially be done in the constructor
var dict = Controls.OfType<TextBox>().ToDictionary(x => x.Name);
for (int i = 0; i < 19; i++)
{
dict[$"s{i}s"].Text = $"{seg[i].Start:X8}";
dict[$"s{i}e"].Text = $"{seg[i].End:X8}";
}
Note : This code is untested and only a guide to a possible solution
I'd be tempted to do it this way. First create two lists of your controls, the starts and the ends:
var starts = new List<TextBox>
{
s0s,
s1s,
//...
s19s
};
var ends = new List<TextBox>
{
s0e,
s1e,
//...
s19e
};
Then loop over each list:
var i = 0;
foreach (var start in starts)
{
start.Text = seg[i].start.ToString("X8");
++i;
}
i = 0;
foreach (var end in ends)
{
start.Text = seg[i].end.ToString("X8");
++i;
}
Your indexes and control numbers would need to line up perfectly though.
Note: Like TheGeneral's code, this is untested (neither of us wants to create a form with 38 text boxes with specific names)
Based on the textboxes names I would suggest alternative approach to use control designed to display collection of things - DataGridView would be one of the options.
With data binding you can achieve little bit more maintainable code
public class MyItem
{
public int Start { get; set; }
public int End { get; set; }
}
In the form create a datagridview with two bounded columns, you can do this in winforms designer without manually writing the code below.
// constructor
public MyForm()
{
var startColumn = new DataGridViewTextBoxColumn();
startColumn.DataPropertyName = "Start"; // Name of the property in MyItem class
startColumn.DefaultCellStyle.Format = "X8";
var endColumn = new DataGridViewTextBoxColumn();
endColumn.DataPropertyName = "End"; // Name of the property in MyItem class
endColumn.DefaultCellStyle.Format = "X8";
myDataGridView.Columns.AddRange(startColumn, endColumn);
myDataGridView.AutoGenerateColumns = false;
}
private void Form1_Load(object sender, EventArgs e)
{
var items = new List<MyItem>
{
new MyItem { Start = 10, End = 20 },
new MyItem { Start = 11, End = 19 },
new MyItem { Start = 12, End = 18 }
};
myDataGridView.DataSource = items;
}
firstly when you create they variables insert them all to an array. then run a loop as following:
for (int i; int < 19(your list); i++)
{
your list[i].Text = seg[i].start.ToString("X8");
your list[i].Text = seg[i].end.ToString("X8");
}
Target:
To write in the label text, but the label ID is assigned by a string.
Problem:
It doesn't work, no errors given. I looked in most places for an answer but nothing helped!
My Code:
string asdfj = treeView2.SelectedNode.Text;
string adqien = System.IO.Path.Combine(dir7, asdfj);
string[] tnsop = System.IO.File.ReadAllLines(#adqien);
h1a.Text = "100";
for (int o = 2; o > 6; o++)
{
//This is the label name e.g "h2a',h3a" etc
string tempc = string.Format("h" + o.ToString() + "a");
foreach (Control ctr in this.Controls)
{
if (ctr is Label)
{
if (ctr.Name == tempc)
{
ctr.Text = tnsop[o];
}
}
}
}
I also consulted this post:
Use string variable content as label ID to update label.Text, I get error - 'string' does not contain a definition for 'Text'
You can do it simply like:
this.Controls.Find(labelname).Text = Value;
or
this.Controls.OfType<Label>().FirstOrDefault(x => x.Name == labelName).Text = Value;
The for loop
First of all, this is wrong for (int o = 2; o > 6; o++).
It starts at o = 2, then checks if o > 6, which is false, because o = 2, and then skips the loop.
I guess you wanted to write: for (int o = 2; o < 6; o++). I am not sure about that, fix it as appropiate.
Addendum: This would have been easily discovored by debugging and stepping. You can start by adding a break point on your code (in Visual Studio you can place your cursor on the desired line and press F9 - by default) and then run in the debugger. When the a line with the break point is reached, the debbuger stops the execution and let you inspect the values of the variables, the call stack, etc. You can then step with F10 or F11 (if you want to inside a method call) and see how the code evolves. You would notice it does not enter the for loop.
Finding the labels
If finding the label still does not work, I would guess the problem is that the labels are not directly on the form or that they do not have the given name.
You can use this.Controls.Find(name, searchAllChildren) to get the labels you need.
That is:
string labelName = string.Format("h" + o.ToString() + "a");
Control[] control = this.Controls.Find(labelName, true);
Note: Yes, I can figure out it is the name of the label by how you use it. Using a comment to tell me saves some time... however, please use better variable names. You won't need a comment to tell me this is the name of the label if the variable name says so.
You still need to check it for the label:
string labelName = string.Format("h" + o.ToString() + "a");
Control[] controls = this.Controls.Find(labelName, true);
foreach (Control control in controls)
{
if (control is Label) // if (control.GetType() == typeof(Label))
{
// ...
}
}
Building a Dictionary
However, I would advice against doing this every time. Instead, I suggest to build a dictionary:
Dictionary<string, Label> labels;
// ...
labels = new Dictionary<string, Label>();
for(int o = 2; o < 6; o++)
{
string labelName = string.Format("h" + o.ToString() + "a");
Label label = GetLabel(labelName);
labels.Add(labelName, label);
}
// ...
private Label GetLabel(string labelName)
{
Control[] controls = this.Controls.Find(labelName, true);
foreach (Control control in controls)
{
if (control is Label) // if (control.GetType() == typeof(Label))
{
return control as Label;
}
}
return null;
}
Note: I suggest to make the dictionary a field and initialize it only once during the form load.
This separates the responsability of finding the labels from reading the file (which is external to the program). Allowing you to test if it can find the right controls without the need of a file.
It will also make the case where the Label is not found visible (we just added a null to the dictionary).
And then use it:
string[] tnsop = System.IO.File.ReadAllLines(#adqien);
for (int o = 2; o < 6; o++)
{
string labelName = string.Format("h" + o.ToString() + "a");
label = labels[labelName];
label.Text = tnsop[o];
}
The code above should throw NullReferenceException if the label was not found while building the dictionary.
Simplify
I guess we can do better. The designer will create fields for your labels, you can just add them to the dictionary:
Dictionary<string, Label> labels;
// ...
labels = new Dictionary<string, Label>();
labels["h2a"] = h2a;
labels["h3a"] = h3a;
labels["h4a"] = h4a;
labels["h5a"] = h5a;
// ...
string[] tnsop = System.IO.File.ReadAllLines(#adqien);
for (int o = 2; o < 6; o++)
{
string labelName = string.Format("h" + o.ToString() + "a");
label = labels[labelName];
label.Text = tnsop[o];
}
Note: There are plenty of opportunities for more modern syntax, including collection initialization and the var keyword.
Addendum: I am unrolling the loop in the above code, this is ok for maintainability if the number of iterations small, in fact, it is a common optimization. You could, in theory do it for the other loop too.
PS. An array will do
I noticed, after finishing writing, that the code only needs to look up by an int o.
We can rework to use int for dictionary keys:
Dictionary<int, Label> labels;
// ...
labels = new Dictionary<int, Label>();
labels[2] = h2a;
labels[3] = h3a;
labels[4] = h4a;
labels[5] = h5a;
// ...
string[] tnsop = System.IO.File.ReadAllLines(#adqien);
for (int o = 2; o < 6; o++)
{
label = labels[o];
label.Text = tnsop[o];
}
Now we have less concatenations, and a simpler code.
We could, in fact, be using an array:
Label[] labels;
// ...
labels = new Label[4];
labels[0] = h2a;
labels[1] = h3a;
labels[2] = h4a;
labels[3] = h5a;
// ...
string[] tnsop = System.IO.File.ReadAllLines(#adqien);
for (int o = 2; o < 6; o++)
{
label = labels[o - 2];
label.Text = tnsop[o];
}
Notice I did offset the indexes to be able to use the array from index 0.
I have a form (Windows Forms) with dynamically created textboxes:
TextBox[] tbxCantServ = new TextBox[1];
int i;
for (i = 0; i < tbxCantServ.Length; i++)
{
tbxCantServ[i] = new TextBox();
}
foreach (TextBox tbxActualCant in tbxCantServ)
{
tbxActualCant.Location = new Point(iHorizontal, iVertical);
tbxActualCant.Name = "tbx" + counter++;
tbxActualCant.Visible = true;
tbxActualCant.Width = 44;
tbxActualCant.MaxLength = 4;
this.Controls.Add(tbxActualCant);
}
Now I want to fill them with data, how could I do that?
If I created some textboxes dynamically with the names:
"tbxActualServ.Name = "txt" + counter;"
How can I write in them? How can I access to them?
For example, if I have created tbx1, tbx2 and tbx3, I would have a "for" that fills tbx1.Text with "1", tbx2.Text with "2", and tbx3.Text with "3".
something like
"for from i=0 to counter {
tbx[i] = i
}"
of like:
this.Controls.OfType<TextBox>().Where(r => r.Name == "tbx" + counter).¿¿Write??(r => r.Text = i).ToString();
Thanks!
You could do something like this:
this.Controls.OfType<TextBox>().ToList<TextBox>().ForEach(tb => tb.Text = "bla bla");
Evening,
Guessing from your tags that this is a web forms project.. Im going to have to make some other assumptions.
I am guessing that you are creating your text boxes in code, something like
TextBox tb1 = new TextBox();
form1.Controls.Add(tb1);
TextBox tb2 = new TextBox();
form1.Controls.Add(tb2);
If this is the case then I believe that you could do something like this:
for (int i = 0; i < 2; i++)
{
TextBox tb1 = page.findControl("tb" + i.ToString());
tb1.Text = "This is number " + i.ToString();
}
There is another alternative, you could keep a collection of the controls as you create them, you could then iterate over the collection.
To be honest, without more details about your code it will be difficult to give a full answer, I think that this answers what you are looking for, if not update your question with more details and more of the code (the code where you are dynamically creating the controls would be useful)
While it's possible to access controls by their names (the way you do it depends on the technology - are you using WinForms, WPF, Web Forms, ...?), using an array of controls is a much better solution. Here's some pseudo-C#:
MyControl[] controls = new MyControl[length];
for(int n = 0; n < controls.Length; n++)
{
controls[n] = new MyControl(...);
}
// ...
for(int n = 0; n < controls.Length; n++)
{
DoSomethingWith( controls[n] );
}
I am trying to do something like this:
for (int i = 1; i < nCounter ; i++)
{
string dvName = "dv" + i.ToString();
System.Windows.Forms.DataGridView dvName = new DataGridView();
// other operations will go here..
}
As you can guess, what I am trying to do is at i == 1, create a DataGridView with name dv1, and at i == 2, create a DataGridView with name dv2, but I can't.
Visual studio squiggles saying "a local variable named dvName is already delared in this scope" I also tried the following:
for (int i = 1; i <nCounter ; i++)
{
System.Windows.Forms.DataGridView dv & i = new DataGridView();
// other operations will go here..
}
But VS squiggles again, I hope you understood what I am trying to accomplish. Can anyone suggest how can I do this?
What you really need is a Dictionary<int, DataGridView> grids. Populate it in your for loop (grids[i] = new DataGridView();) and then, later, use the required grid (grids[someCalculatedIndex])
Hope this helps.
try a data structure where you can hold your variables eg dict etc
System.Collections.Generic.Dictionary<string,System.Windows.Forms.DataGridView>
grids = new Dictionary<string,System.Windows.Forms.DataGridView>();
for (int i = 1; i <nCounter ; i++)
{
grids.Add("dv" + i.ToString(), new DataGridView());
}
// to work on grid 1
DataGridView grid1 = grids["dv1"];
// so on
So your are trying to create the variable name dynamically? That's not possible. Why not use an Array or a List (or even a Dictionary)? Or do you want to just set the name of the control?
var list = new List<DataGridView>();
for (int i = 1; i <nCounter ; i++)
{
System.Windows.Forms.DataGridView dvName = new DataGridView();
dvName.Name = "dv" + i.ToString();
list.Add(dvName);
// other operations will go here..
}
foreach (var dv in list)
{
...do something...
}
DataGridView secondDv = list.Single(dv=>dv.Name == "dv2");
secondDv.DoSomething()
Not clear want you want to do...
I want to add controls to my aspx web form at runtime using C#.
I would like to write a generic function which will create any type of control (Eg: textbox, lable, button etc).
Any ideas please.
Thanks
BB
You can do this, as long as the control types you want to use all have a default constructor.
T AddControl<T>() where T : WebControl, new()
{
T ctrl = new T();
...
return ctrl;
}
I suppose you could do something like this:
public void CreateControl<W>(Func<W> controlConstructor) where W : WebControl
{
W control = controlConstructor();
//add control and configure it, etc etc
}
Add TextBoxes Control to Placeholder
private void CreateTextBoxes()
{
for (int counter = 0; counter <= NumberOfControls; counter++)
{
TextBox tb = new TextBox();
tb.Width = 150;
tb.Height = 18;
tb.TextMode = TextBoxMode.SingleLine;
tb.ID = "TextBoxID" + (counter + 1).ToString();
// add some dummy data to textboxes
tb.Text = "Enter Title " + counter;
phTextBoxes.Controls.Add(tb);
phTextBoxes.Controls.Add(new LiteralControl("<br/>"));
}
}
In CreateTextBoxes method I loop through ‘n’ numbers of controls that we wants to create dynamically in phTextBoxes placeholder.