Programatically reference ascending variable names (var1, var2, ... ) - c#

I'm currently coding a project that can take up to 200 entries of a specific product, as determined by user input. Basically, my GUI loads, and I use jQuery to dynamically build the entries whenever there is a change to the amount field. When using jQuery, I simply give each of them ids in the form of variable1, variable2, ...., variableX (where X is the amount of entries indicated). Small snippet of code to clarify:
for(var i = 1;i <= amount_selected; i++) {
$('table_name tr:last').after('<tr><td><input type="text" id="variable' + i + '"></td></tr>');
}
Now when I try to move to the back end, I'm trying to reference these variable names by putting them in a list. I went ahead and put them in a list of HtmlInputText, to call the Variable names from the list itself. (This would save having to call all (up to 200) methods manually, which is really not an option).
So what I did (in C#) was:
List<HtmlInputText> listvar = new List<HtmlInputText>();
for(int i = 1; i <= amount_selected; i++) {
string j = "variable" + Convert.ToString(i);
HtmlInputText x = j;
listvar.Add((x));
samplemethod(listvar[i]);
}
But it's not working at all. Does anyone have any ideas as to how this would be done, without doing so manually? I know my logic might be completely off, but hopefully this illustrates at least what I'm attempting to do.

I'm assuming these inputs are in a form? If you're submitting then you can access the text boxes from the Request object:
List<string> results = new List<string>();
for (int i = 1; i <= amount_selected; i++)
{
string s = String.Format("{0}", Request.Form["variable" + Convert.ToString(i)]);
results.Add(s);
}

you could do $("#variable" + Convert.ToString(i)).val()

Related

C# Pull items from array based on string

Not sure if this is the best way to do this but I've created a 2D array from values in an excel file that i want to use as variables within my application that control where to look for things like file paths and files.
The array is built and all data from the file is contained within it:
for (int i = 0; i <= bindingSourceConfig.Count - 1; i++) // for each row in the binding source data
{
for (int j = 0; j <= 2 - 1; j++) // for each column, only need one and 2
{
System_Var_Array[i, j] = (bindingSourceConfig.DataSource as DataTable).Rows[i][j].ToString();
}
}
Now i want to be able to look in the array for my variable say "Project_Directory" and have it return "C:\Users\User\Dropbox\default\master\support"
Is this even possible?
EDIT 1:
Purpose of doing it this way is to make an easily customizable/configurable multi project environment where by anyone can simply edit the paths in the excel file and import that file into the application.
I can not in my incompetence see a way of setting these 'variables' at a class level without first extracting the 'variable' and the 'value' from the excel data.
Is there a simple way of looking up the 'variable' in bindingSource?
EDIT 2:
debugger image
var name = "Project_Directory";
string value = null;
for (int i = 0; i<System_Var_Array.GetLength(0); i++) {
if (System_Var_Array[i,0]==name) {
value = System_Var_Array[i,1];
break;
}
}
After the loop stop, value will contain the data you need, assuming it exists (otherwise it will be null. A far simpler approach will be using Dictionary<string,string>, if you generate it with
var systemVars = new Dictionary<string,string>();
var dt = bindingSourceConfig.DataSource as DataTable;
for (int i = 0; i < bindingSourceConfig.Count; i++) // for each row in the binding source data
{
systemVars[dt.Rows[i][0].ToString()] = dt.Rows[i][1].ToString();
}
then to get the value for "Project_Directory", simply call
var value = systemVars["Project_Directory"];
You should use an appsettings file for this instead, it's the dotnet standard solution for this sort of thing. Please see https://learn.microsoft.com/en-us/dotnet/core/extensions/configuration.

How to import from a dynamic array

My program has to place objects on a map, i have to get the informations about the objects from a text file but my problem is that there is no limit in objects so when i write my code i don't know if someone wants to place 1 or 10 or 5 objects. Every object has a separate line where you can give the parameters for example x,y coordinates on the map to place etc etc.
I figured out that i will ask the user to write in a line before the objects the number of objects he wants to add.Here is my example :
txt file:
200<----not important here
10000<----not important here
5<---number of objects
2,5/60-60<--object
4,5/70-70<--object
5,5/80-80<--object
1,1/30-30<--object
10,10/100-100<--object
10,1/5<----not important here
height,weight/x-y
And vs throws out of range exception. Hope u understood my english and my problem
int numberofObjects = int.Parse(data[2]);
Targets[] TargetsGet = new Target[numberofObjects];
int j = 0;
for (int i = 4; i <= numberofObjects+3; i++)
{
targets[j] = new Target(int.Parse(data[i].Split(',')[0]), int.Parse(data[i].Split('/')[0].Split(',')[1]), new Coordinate(int.Parse(data[i].Split('/')[1].Split('-')[0]),int.Parse( data[i].Split('-')[1])));
j++;
}
return TargetsGet;
}
First of all, your solution works.
If you don't want to ask the user to specify the number of objects, you can use a list instead of an array and use a separator at the end of the object list. For example:
List<Targets> TargetsGet = new List<Target>();
int j = 0;
while(data[j]!="separator")
{
targets.Add(new Target(int.Parse(data[j].Split(',')[0]), int.Parse(data[j].Split('/')[0].Split(',')[1]), new Coordinate(int.Parse(data[j].Split('/')[1].Split('-')[0]),int.Parse( data[j].Split('-')[1])));
j++;
}
return TargetsGet.ToArray();
}
The file should be modified so the string "separator" will be after the object list:, for example:
200<----not important here
10000<----not important here
2,5/60-60<--object
4,5/70-70<--object
5,5/80-80<--object
1,1/30-30<--object
10,10/100-100<--object
separator
10,1/5<----not important here
height,weight/x-y

how can i access a textbox which create dynamically?

when i creat unlimited textbox in gridview dynamically how can i access them?
for example:
int uste_uzaklik = 30;
int nesne = ListBox1.Items.Count;
Array.Resize(ref textboxarray, nesne * nesne);
for (int str = 0; str < nesne; str++)
{
for (int stn = 0; stn < nesne; stn++)
{
textboxarray[idm] = new TextBox();
textboxarray[idm].Font.Bold = true;
textboxarray[idm].Font.Name = "Verdana";
textboxarray[idm].ID = idm.ToString();
textboxarray[idm].ToolTip = textboxarray[idm].ID;
GridView2.Rows[str].Cells[stn + 1].Controls.Add(textboxarray[idm]);
if (str == stn) textboxarray[idm].Enabled = false;
uste_uzaklik += 30;
idm++;
}
}
i add texboxes in gridview...you can imagine a matris...
there is no problem...
but when i access them like this:
if (((TextBox)(GridView2.Rows[str].Cells[stn].FindControl(idm.ToString()))).Text != null)
{
matris[i, j] = Convert.ToInt32(GridView2.Rows[str].Cells[stn].Text);
}
occur an error
Object reference not set to an instance of an object.
how can i solve this problem?
References you have to controls don't cease to exist you add them to another control. You've already created an array of your TextBoxes, and you should use that to access them instead of trying to dig into the GridView in which you've added them every single time you want to change them.
Granted, you're going from a one-dimensional array of TextBoxes to a two-dimensional layout within the GridView, so you'll either have to find some way to establish how the indices match up between the two. Or, more easily, you could just turn textboxarray into a two-dimensional array and just have it exactly match the way it's laid out in the GridView. Either way, I think it'll be a lot less work than having to muck around in the GridView.

I have four webbrowsers, each named web1, web2, etc... How do I use a for loop for them?

I have a for loop, and four webbrowsers. They are called:
Web1
Web2
Web3
Web4
I have a for loop:
for (int i = 1; i <= 4; i++)
I want to write the code once, and have it execute on all four browsers. I thought it was something like this:
web[i.toString()]
However that outputs:
The name "web" does not exist in the current context
How would I do it?
Use an array
var webBrowsers = new[] { Web1, Web2, Web3, Web4 };
for(int i = 0; i < webBrowsers.Length; i++)
{
webBrowsers[i]... // Do something with each
}
In general, whenever you have variables with serial names (like Web1..Web4) that's a good indication that you should probably use an array instead. Personally, I'd refactor the code so that you remove all references to the individual webBrowser controls, and use an array exclusively. However, that's probably beyond the scope of this question.
Further Reading:
Arrays Tutorial (C#)
You would need to recover the control by name, not statically, but dynamically:
var matches = this.Controls.Find(string.Format("Web{0}", i), true);
// this means you can't find that control
if (matches.Length == 0) { continue; }
// now you can cast the first control if you'd like
var web = matches[0] as WebBrowser;

Iterating over an array using index and assigning values depending on index

I was facing this problem earlier today, and since I could not find a satisfactory solution, I decided to change my class design, and have seperate properties such as Tag 1, Tag 2, Tag 3 etc.
My main problem is the fact that I need to bind a grid to an object that contains a list among other properties and I need to show each item in the list as a separate column which I am unable to do. Hence I am resorting to declaring variables separately. Original question is here...
Now, I'm facing one of the most common design problem that probably every programmer has at some point of time. Here is the code to demonstrate it,
for (int i = 0; i < tags.Length; ++i) // Length not known here.
{
if(i==0){
tag1 = tags[0];
}
else if(i == 1){
tag2 = tags[1];
}
else if(i == 2){
tag3 = tags[2];
}
....
}
Here tags is a string array.
I was wondering if there is a more elegant way to do this. Another thing to note is that the efficiency of this loop decreases as it progresses, since with more iterations it has to check more conditions. If we could remove a condition after it had become true once it would speed up each iteration since we know that each condition will become true only once in all the iterations
Moved answer about DataGridView and using ComponentModel to the correct question:
Displaying a list of object containing a list in a grid view
Briefing
The DataGridView controll supports the ComponentModel namespace so that you can create classes that appear to have properties that don't exist. It is the same mechanism the PropertyGrid uses.
The sample code is in this answer of that question:
https://stackoverflow.com/a/13078735/195417
OLD ANSWER
This was my previous answer, when I didn't realize the real question was about the DataGridView control.
Isn't this the same as setting the values directly:
this.tag1 = tags[0];
this.tag2 = tags[1];
this.tag3 = tags[2];
EDIT: as you sayd you don't know how many variables will be needed, then you need only one, and that is a list:
var list = new List<string>();
for (int i = 0; i < tags.Length; ++i)
{
list.add(tags[i]);
}
If all you want is to copy all values, you can even do this:
var list = new List<string>(tags);
Tell me whether this is what you want or not... maybe I have misunderstood the question.
The whole loop is pointless. But unless the tags array length is always going to be the same, you have to be sure not to go out of bounds...
if(tags.Length >= 1) this.tag1 = tags[0];
if(tags.Length >= 2) this.tag2 = tags[1];
if(tags.Length >= 3) this.tag3 = tags[2];
if(tags.Length >= 4) this.tag4 = tags[3];
if(tags.Length >= 5) this.tag5 = tags[4];
... so on for however many this.tag# you have.
This is essentially the same:
for(int index = 0; index < tags.Length[]; index++){
switch(index){
case 0:
tag1 = tags[0];
break;
// And so on
}
}

Categories