So I have this kind of code (I'm assigning values to XAML elements
), which begs for a "for" loop.
Day1d.Text = string.Format("{0:dd/MM}", DateTime.Today.AddDays(1));
Day2d.Text = string.Format("{0:dd/MM}", DateTime.Today.AddDays(2));
Day3d.Text = string.Format("{0:dd/MM}", DateTime.Today.AddDays(3));
Day4d.Text = string.Format("{0:dd/MM}", DateTime.Today.AddDays(4));
Day1t.Text = "°" + (myWeatherForecast.forecastlist[1].temp).ToString();
Day2t.Text = "°" + (myWeatherForecast.forecastlist[2].temp).ToString();
Day3t.Text = "°" + (myWeatherForecast.forecastlist[3].temp).ToString();
Day4t.Text = "°" + (myWeatherForecast.forecastlist[4].temp).ToString();
But all my attempts to include "i" in variable name failed miserably. Is there a way to achieve this?
You can create a loop where you iterate over the instances:
int counter = 1; // are you sure it shouldn't start at 0?
foreach (TextBox tb in new TextBox[] { Day1d, Day2d, Day3d, Day4d })
{
tb.Text = string.Format("{0:dd/MM}", DateTime.Today.AddDays(counter));
counter++;
}
counter = 1;
foreach (TextBox tb in new TextBox[] { Day1t, Day2t, Day3t, Day4t })
{
tb.Text = "°" + (myWeatherForecast.forecastlist[counter].temp).ToString();
counter++;
}
You can't compose the name of the variable using another variable. The way to do this would be to create a List and then iterate over that List
var textBoxes1 = new List<TextBox> { Day1d, Day2d, Day3d, Day4d }
var textBoxes2 = new List<TextBox> { Day1t, Day2t, Day3t, Day4t }
foreach (var textbox in textBoxes1)
{
var index = textBoxes1.IndexOf(textBox) + 1;
textbox.Text = string.Format("{0:dd/MM}", DateTime.Today.AddDays(index));
}
foreach (var textbox in textBoxes2)
{
var index = textBoxes2.IndexOf(textBox) + 1;
textbox.Text = "°" + (myWeatherForecast.forecastlist[index].temp).ToString();
}
NOTE: You can solve this in different ways:
using arrays instead of lists
keeping your own counter, instead of doing IndexOf
using a for loop, instead of a foreach
Which one is better is mostly based on opinion (although my method is not the fastest, but it doesn't matter if you only have 4 items)
You can use FindName assuming you are using WPF.
Try:
for (int i = 1; i < 5; i++)
{
((TextBox)this.FindName("Day" + i + "d")).Text = string.Format("{0:dd/MM}", DateTime.Today.AddDays(i));
((TextBox)this.FindName("Day" + i + "t")).Text = "°" + (myWeatherForecast.forecastlist[i].temp).ToString();
}
Related
I have a dropdownlist (specialty) and I want to loop through the number of options in the specialty and add it an array:
string[] strSpecArrayForTopics = new string[Specialty.Items.Count]; //total number of specialty items
foreach (ListItem li in Specialty.Items) //for each item in the dropdownlist
{
strSpecArrayForTopics[Specialty.Items.Count] = li.Value; //add the value to the array (The error happens here)
lblSpec.Text = lblSpec.Text + "<br />" + li.Value; //this works fine.
}
So let's say the specialty dropdownlist has:
All
Card
Intern
Rad
The array should be:
strSpecArrayForTopics[0] = "All";
strSpecArrayForTopics[1] = "Card";
strSpecArrayForTopics[2] = "Intern";
strSpecArrayForTopics[4] = "Rad";
var strSpecArrayForTopics = Specialty.Items.Cast<ListItem>().Select(x => x.Value).ToArray();
You need to add index to your array. Check the below code:
string[] strSpecArrayForTopics = new string[Specialty.Items.Count]; //total number of specialty items
int index = 0;
foreach (ListItem li in Specialty.Items) //for each item in the dropdownlist
{
strSpecArrayForTopics[index] = li.Value; //add the value to the array (The error happens here)
lblSpec.Text = lblSpec.Text + "<br />" + li.Value; //this works fine.
index = index + 1;
}
You are looking for a for loop.
for(int i = 0;i < Specialty.Items.Count; i++) //for each item in the dropdownlist
{
strSpecArrayForTopics[i] = Specialty.Items[i].Value;
lblSpec.Text = lblSpec.Text + "<br />" + Specialty.Items[i].Value;
}
I also used this as a solution:
string[] strSpecArrayForTopics = new string[Specialty.Items.Count];
int k = 0;
foreach (ListItem li in Specialty.Items)
{
strSpecArrayForTopics[k] = li.Value;
lblSpec.Text = lblSpec.Text + "<br />" + li.Value;
k++;
}
You can also use LINQ for this.
using System.Linq;
string[] strSpecArrayForTopics = Specialty.Items.Select(v => v.Value).ToArray();
if .Value is of type object, use the following.
string[] strSpecArrayForTopics = Specialty.Items.Select(v => (string)v.Value).ToArray();
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;
}
I have four arrays of equal length
I am using those arrays in foreach loops.
I am using four variables(i,j,k,l) to increment and to proceed
I am writing my code inside the four nested loops, that code should execute when i=0,j=0,k=,0,l=0
i=1,j=1,k=1,l=1
i=2,j=2,k=2,l=2
.....(depending on the array length)
Please suggest me the code for this required segment.
int i = 0, j = 0, k = 0, l = 0;
foreach (string fieldName in splitFieldnames)
{
i = 0;
foreach (string dataType in splitDatatypeNames)
{
j = 0;
foreach (string controlName in SplitControlNames)
{
k = 0;
foreach (string controlType in splitControlTypeNames)
{
if (i == j && j == k && k == l)
{
if (controlType == "textbox" && dataType == "string")
{
Response.Write("_Student." + fieldName + "= " + controlName + ".Text;");
l++;
break;
}
}
k++;
}
j++;
}
i++;
}
}
I think using LINQ would save you a lot of manual coding:
static void Main(string[] args)
{
var splitFieldnames = new string[] { "field1", "field2", "field3" };
var splitDatatypeNames = new string[] { "datatype1", "string", "string" };
var SplitControlNames = new string[] { "control1", "control2", "control3" };
var splitControlTypeNames = new string[] { "combobox", "textbox", "textbox"};
// this code can handle different sized arrays, but is based strictly
// on the size of the splitFieldnames array as the base.
var splitMerged = splitFieldnames.Select
((c, idx) =>
new
{
fieldName = c,
dataType = splitDatatypeNames.Length > idx ?
splitDatatypeNames[idx] : "",
controlName = SplitControlNames.Length > idx ?
SplitControlNames[idx] : "",
controlTypeName = splitControlTypeNames.Length > idx?
splitControlTypeNames[idx] : "",
});
foreach (var item in splitMerged
.Where(c => c.controlTypeName == "textbox" && c.dataType == "string"))
{
Response.Write("_Student." + item.fieldName + "= "
+ item.controlName + ".Text;");
}
The resulting output would be look like:
_Student.field2= control2.Text;
_Student.field3= control3.Text;
I hope that's what you're looking for, LOL...
I think that in this case a DataTable would be better than 4 arrays, and algorithm you require will be trivial with such data structure.
Use for instead of foreach
for (int i = 0; i < splitFieldnames.Length; i++)
{
string fieldName = splitFieldnames[i];
for (int j = 0; j < splitDatatypeNames.Length; j++)
{
string dataType = splitDatatypeNames[j];
for (int k = 0; k < SplitControlNames.Length; k++)
{
string controlName = SplitControlNames[k];
for (int l = 0; l < splitControlTypeNames.Length; l++)
{
string controlType = splitControlTypeNames[l];
if (i == j && j == k && k == l)
{
if (controlType == "textbox" && dataType == "string")
{
Response.Write("_Student." + fieldName + "= " + controlName + ".Text;");
break;
}
}
}
}
}
}
Note also that break will only break out of the innermost loop! Consider using a return statement instead.
UPDATE (in response to your edit):
The solution is simple, use only one index variable and only one for-loop instead of a lot of foreach-loops
for (int i = 0; i < splitFieldnames.Length; i++)
{
if (splitControlTypeNames[i] == "textbox" && splitDatatypeNames[i] == "string")
{
Response.Write("_Student." + splitFieldnames[i] + "= " + SplitControlNames[i] + ".Text;");
break;
}
}
(Assuming that you want to stop after the first match. If you want to output all string textboxes, drop the break statement.)
Ok, this code is really simple.. If you only need to show the data when i=j=k=l, then no need for any loop, or even for the existence of i,j,k,l.
If you can assure me that all this strings in whatever thing (a collection? an array? a dictionary?) are ordered, is ok.
If they are ordered, then throw away all the for each, and just access each one by position for all the controls you have in the collection that has the minimun.
If all this collection are not ordered, then this is totally uselles, since it will produce differents results on each run.
I will edit this answers with some code, once you can tell me if this is ordered or not.
EDIT:
First of all, you need to check what collection has the least items (since you can't go beyond that)... I don't know the types of this things (you didn't provide them), so let's assume they have a count property.
int minimun = splitFieldnames.count;
if (splitDatatypeNames.count < minimun)
minimun = splitDatatypeNames.count;
if (SplitControlNames.count < minimun)
minimun = SplitControlNames.count
if (splitControlTypeNames.count < minimun)
minimun = splitControlTypeNames.count
once you have the minimun value (since you can't go beyond that), just iterate on that and print whatever you want
for (int i = 0; i < minimun;i++)
{
if (splitControlTypeNames[i].tostring() == "textbox" && splitDatatypeNames[i].tostring() == "string")
{
//Response.Write("_Student." + fieldName + "= " + controlName + ".Text;");
//Also, a parametric string would be better ;)
string result = string.format("_Student.{0}= {1}.Text;",splitFieldnames[0].tostring(),SplitControlNames[0].tostring());
Response.Write(result);
l++;
}
}
I don't know the types, so I'm assuming that they have a tostring method an a count property
If what you are trying to accomplish is process the same index in the four arrays, just use one loop and use a counter to access the value in each array in that one loop:
foreach(string fieldName in SplitControlNames)
{
dataType = splitDatatypeNames[arrayPosition];
controlName = SplitControlNames[arrayPosition];
controlType = splitControlTypeNames[arrayPosition];
if (controlType == "textbox" && dataType == "string")
Response.Write("_Student." + fieldName + "= " + controlName + ".Text;");
arrayPosition++;
}
Or, create and populate a structure that has four values in it (fieldName, dataType, controlName, controlType) and have one array of that structure
HtmlAnchor[] anchorToConvert = new HtmlAnchor[]{
clickHere,
leavePage};
Button[] buttonToConvert = new Button[]{
login,
register};
i = 0;
for (i = 0; i < anchorToConvert.Length; i++)
{
DataRow[] result = ds.Tables[0].Select("htmlControl LIKE '" + anchorToConvert[i].ID.ToString() + "'");
if (result.Length > 0)
{
anchorToConvert[i].InnerHtml = result[0]["phrase"].ToString();
}
}
i = 0;
for (i = 0; i < buttonToConvert.Length; i++)
{
DataRow[] result = ds.Tables[0].Select("htmlControl LIKE '" + buttonToConvert[i].ID.ToString() + "'");
if (result.Length > 0)
{
buttonToConvert[i].Text = result[0]["phrase"].ToString();
}
}
I have two arrays of html elements i need to loop through, and use the elements id attribute to select content from a database. Rather than having to create two arrays and loop through them individually, is there someway i can make a more generic array that can contain both buttons and anchors?
You could use a list and check the type of the control in the list when you're looping through:
List<Control> ctrl = new List<Control>();
HtmlAnchor anchor = new HtmlAnchor();
anchor.ID = "myAnchor";
ctrl.Add(anchor);
Button btn = new Button();
btn.ID = "MyBtn";
ctrl.Add(btn);
foreach (Control c in ctrl.ToList())
{
if (c is Button)
{
// Do Something
}
}
Both HtmlAnchor and Button inherit from Web.UI.Control (though not directly).
If that is the type of the array, both of these types (HtmlAnchor and Button) can be assign to the array.
I'm pulling data from Dynamics AX 2009 from c# using the following code snippet. This works fine, except for those cases where the underlying field type is a dimension. I want to be able to "flatten" array types when I return them but can't see any way to do this. Any ideas anyone?
axRecord = ax.CreateAxaptaRecord(tableName);
axRecord.ExecuteStmt(strQuery);
// Loop through the set of retrieved records.
using (StreamWriter sw = File.CreateText(path))
{
AxaptaObject axDictTable = ax.CreateAxaptaObject("SysDictTable",axRecord.get_Field("tableid"));
outputRow = null;
List<int> ids = new List<int>();
for (int i = 1; i <= (int)axDictTable.Call("fieldCnt"); i++)
{
AxaptaObject axDictField = ax.CreateAxaptaObject("DictField", axRecord.get_Field("tableid"), axDictTable.Call("fieldCnt2ID", i));
outputRow += ((string)axDictField.Call("Name")) + ",";
ids.Add((int)axDictTable.Call("fieldCnt2ID", i));
}
sw.WriteLine(outputRow);
while (axRecord.Found)
{
outputRow = null;
foreach(int i in ids)
outputRow += axRecord.get_Field(i).ToString().Replace(",", "") + ",";
sw.WriteLine(outputRow);
axRecord.Next();
}
}
You could check if the field is an array by (X++ code), and then work this out your way to "flatten" it:
currentTable = new SysDictTable(tablenum(ledgerJournalTable));
for(i = 0;i<=currentTable.fieldCntWithoutSys();i++)
{
currentField = new SysDictField(currentTable.id(), currentTable.fieldCnt2Id(i));
if(currentField.arraySize() > 1)
{
//your code
}
}
You can always safely cast the object like this:
var o = ax.CreateAxaptaObject() as AxaptaObject;
if(o != null)
{
...code
}