c# - concatenation and properties of TextBox - c#

I'm trying to use something like this:
for (int i = 0; i < 40; i++)
{
string x + i = TextBox + i.Text;
}
Is there any solution for this? I want to use i as an index as if I had an array of TextBox. How can I achieve a textbox's Text property like this?
I want to create for example a string named x1,x2,x3,x4... and value of x1 = TextBox1.Text.
But I could not :(
I have TextBox1,2,3...40 and I just want to pass their text values to new string or string list ex. like x1 = TextBox1.Text, x2 = TextBox2.Text; ..... :(

You're trying to get the Text property from a collection of TextBox - which, by the way, you haven't shown us how you're getting. It's possible that you don't even have an array of TextBox.
If you do, you'd use code like this (note that SomeCodeToGetTextBoxArray() needs to be defined by you):
TextBox[] myTextBoxes = SomeCodeToGetTextBoxArray();
var arrayLength = myTextBoxes.Length;
String[] x = new String[arrayLength];
for (int i = 0; i < arrayLength; i++)
{
x[i] = myTextBoxes[i].Text;
}

What you're looking to do is have a reference to a local variable, field, or property by it's string name that you generate at runtime. The only way to do what you want is to use reflection.
There are different ways to do this depending on if the variable is locally scoped, a field member, or a property member.
Reflection - LocalVariableInfo - FieldInfo - PropertyInfo
Note that while that would be the answer to your question, it is probably better to use an array (or List<T>) and use indexes. Though, it is really impossible to know without knowing what you are trying to do fully (not just in your little snippet). But, it's more likely that an array (or List<T>) is the more correct solution.

Related

Parsing string as int with "Model.x" property in for loop remains in string format

I have a simple form that accepts a number from a radio button selection (1-5) of 11 questions and posts the values into a database as varchar(10) data. I intend to send the user to a result page that lists the sum of these scores through a simple for loop, but when I try parsing the data to integer format, it simply results in zero due to error parsing. Here's an example of my code:
// Q1 - Q11 are the questions in my Db, using Model property
int sum = 0;
int temp = 0;
String question;
for (int i = 11; i >= 1; i--)
{
question = "Model.Q" + i.ToString();
temp = int.Parse(question);
sum += temp;
}
return sum;
What's strange is that if I parse them individually, such as writing:
Int32.TryParse(Model.Q5, out temp);
I am able to parse the data just fine. My console shows that the loop keeps the question variable as "Model.Qx" with quotations, ultimately resulting in 0 for the sum. I have also tried using Int32.TryParse(); for that as well and it resulted in no difference, besides handling the error.
Can a string simply not be parsed if it contains punctuation in concatenation with the i variable, or am I missing something else here? I want to avoid parsing each question individually, as it looks rather ugly in code.
Thanks in advance.
You problem is that you're trying to access a variable by using a string with the same name. This won't work, in the same way that the name gitgecko is not you.
If your model has got a number of properties with similar names, you could write a function to switch between them:
object GetQ(int number)
{
switch(number)
{
case 1: return Model.Q1;
case 2: return Model.Q2;
// etc...
}
}
Or you could change your model to store these variables in an array or list, or whatever is appropriate.
For example, if you've currently got:
class Model
{
string Q1;
string Q2:
// repeated 11 times
You could have:
class Model
{
string[] Q = new string[11];
}
which gives you the ability to do Model.Q[x]

Edit code based on a string during runtime

I have a program in which the user types a string which the code needs to type out using the InputSimulator NuGet package.
Is there a way for me to type the code and fill in the blanks with strings and have it run? here is what it mean:
Inputsimulator sim = new Inputsimulator();
sim.Keyboard.KeyPress(WindowsInput.Native.VirtualKeyCode.VK_A);
(VK_A Would be replaced with "VK_" + MyLetter)
Is there any way to change or make code to run during runtime?
I appreciate any help, thanks.
You can just use the TextEntry method instead:
sim.Keyboard.TextEntry("Say hello!");
I don't know about WindowsInput.Native.VirtualKeyCode.VK_A, but it obviously look like an enum, so they must have incremental integer values, So:
int a = (int)WindowsInput.Native.VirtualKeyCode.VK_A;
would give you the value of VK_A, and VK_B would be a+1, and so on...
int a = (int)WindowsInput.Native.VirtualKeyCode.VK_A;
for(int i=0; i<26; i++)
sim.Keyboard.KeyPress((WindowsInput.Native.VirtualKeyCode)(a + i));
You may use a method like this:
WindowsInput.Native.VirtualKeyCode KeyCode(char chr)
{
int a = (int)WindowsInput.Native.VirtualKeyCode.VK_A;
if( a >= 'A' and a<='Z')
return (WindowsInput.Native.VirtualKeyCode)(chr - a);
//else do other cases
}
And then you can use it like this:
sim.Keyboard.KeyPress(KeyCode('B'));

Passing an argument from a string

I'm new in the c# world and I'm trying to pass an argument dynamically
So I'm doing a small addin on ms Project, and I need to do some calculation when the data is a duration or a Cost, so I have many duration field Duration1,Duration2,... and the same for cost fields
So what I'm doing is simple, I found all duration ID and I put them in my DurationList, after that I make a check, if I select only one column and the ID of this selected column is in my list, I take the name of this field and I try to pass it as an argument
This is a piece of my code, here I'm just working on the duration
using MSProject = Microsoft.Office.Interop.MSProject;
private void Application_WindowSelectionChange(MSProject.Window Window, MSProject.Selection sel, object selType)
{
MSProject.Task task = null;
List <int> DurationList = new List<int> { 188744967,...};
int value= Int32.Parse(Application.ActiveSelection.FieldIDList[1]);
Double Cost=0, CostTotal=0;
if (DurationList.Contains(value)){
string fieldname= Application.ActiveSelection.FieldName[1];
for (int i = 1; i <= sel.Tasks.Count; i++)
{
task = sel.Tasks[i];
Cost = Convert.ToDouble(task.fieldname);
CostTotal += Cost;
}
}
}
but when I tried that I get an error message: "Task" doesn't contain a definition for name and no extension method 'name' accepting a first argument of type 'Task' could be found.
So what my code is excpected to do, it gets the name of my field, it stores it in my fieldname string and after that I want to pass the content of this string as an arugment of my task.fieldname. If I used a suggested field which appear with the small wrench, like cost or duration, my code runs without issues but I need to get something more dynamic
Any idea?
Thanks
I am not sure what you are trying to do. Could you explain your intent differently?
Here are some things I noticed though:
You cannot declare and use the "+=" operator in the same line. Since "+=" is the short-hand for adding a value to the already initialized variable on the left.
i.e: x += 2; is equivelant to x = x + 2; therefor x must be initialized (have a current value) by the time you use the += operator on it. When you say double x += anyValue; that actually means x = x + anyValue and x does not yet have a value.
And as for string argument = "Duration"; are you substituting it for a string which would represent a valid double literal i.e: 1.66? I assume you are.
Without Seeing the Task class definition I cannot be sure, what is going on but I assume it is that argument is not an instance member of Task.
If I finally understand, this is how you would get the value of your Task property named "fieldname":
task = sel.Tasks[i];
var valueofFieldName = task.GetType().GetProperty(fieldname).GetValue(task, null);
Cost = Convert.ToDouble(valueofFieldName);
CostTotal += Cost;

Catching value of the concatenated variable

My environment is: W7 Ultimate 64 bits, VS2010 Ultimate, C#, WinForm, target XP and W7.
With the help of #dasblinkenlight, the concatenation on the for loop was very good.
I feel we are making great progress.
As you ca see, we are putting into the array sMntHour[d,h] the string "csv_001_01" if d=1 and h=1 and so on.
This csv_001_01, csv_001_02,.. ; are variables that contains an integer value.
csv_001_01=5111;
csv_001_02=236; // This is a sample, because has 365 days in normal year
// and 366 days in leaf year. "csv_day_hour"
Directly we could do this:
sMntHour[d,h] = csv_001_01.ToString(); // d is day and h is hour
sMntHour[d,h] = csv_001_02.ToString();
As we put the value of this concatenated variable in the array and not the name of the variables?
for(int d=1;d<=365;d++) //I'll put the code to not leap years.
{
for(int h=1; h<=24; h++)
{
sMntHour[d,h] = string.Format("csv_{0:000}_{1:00}", d, h)
}
}
If I understand what you mean, you have all the variable names and now you want to get their values.
You could do this using Reflection and you can create a dictionary where keys are the variable names and the values are the actual values. It is really hard to help without seeing how these variables are declared, are they fields / properties ? are the private, static ? etc... But something like this should work, in theory:
var type = this.GetType();
var values = sMntHour.OfType<string>()
.ToDictionary(
x => x,
x => (int)type.GetField(x).GetValue(this));
Then you can access the values using values["variable_name"]
Or if you don't want this, instead if you want to access them using index like [d,h] as mentioned in comments, do not store the variable names in the first place instead store the values in your array:
var type = this.GetType();
for(int d=1;d<=365;d++)
{
for(int h=1; h<=24; h++)
{
var name = string.Format("csv_{0:000}_{1:00}", d, h);
sMntHour[d,h] = (int)type.GetField(name).GetValue(this);
}
}
Ofcourse you need to change the type of sMntHour, in order to make it work.

Add TextBox.Text to a list using a for loop

I am trying to take the values in the textboxes, named sequentially from 0-9, and add that to a List using a for loop. I am having problems with the syntax or something.
here is what I have now.
for (int i = 0; i <= amt.Count(); i++)
{
amt[i] = int.Parse(amtBox[i].Text);
}
The error is that amtBox doesnt exist in the current context.
My problem is within the loop where i have amtBox[i].Text. I have tried this several ways and VS always throws an error. I have tried "amtBox" + i and that compiles but then causes an error when I try to do something with it and says "data is of wrong type".
I am new to C# and come from PHP so maybe that is why I think this approach will work. PHP doesnt care about data types where C# really does. I have done this exact thing in PHP many times without any issue.
Any suggestions on another way to do this are appreciated as I am probably coming at this all wrong.
Thanks
One solution would be to declare an array and assign amtBox'es to the individual indexes in the array and then you can iterate on that array.
var amtBoxes = new TextBox[] { amtBox0, amtBox1, .... };
for (int i = 0; i <= amt.Count(); i++)
{
amt[i] = int.Parse(amtBoxes[i].Text);
}
If you end up needing to iterate on your TextBox controls in other places I would consider making the array an instance member of your object.
I suppose that your textbox are named "amtBox" + a number.
(The Name property is "amtBox1" as an example)
In this case you could use
Control[] t = Controls.Find("amtBox" + i, false);
for a code like this
for (int i = 0; i <= amt.Count(); i++)
{
Control[] t = Controls.Find("amtBox" + i, false);
if(t != null && t.Length > 0)
{
amt[i] = int.Parse(t[0].Text);
}
}
My understanding is that you have text boxes named amtBox1, amtBox2, etc., and what you are trying to do is sequence through them. As you point out, this is very easy in PHP. It is possible to do what you're suggesting using reflection, but that is expensive and, in any event, there's probably a better way to do what you're looking for.
You could put all of your amount boxes into an array, and then what you have would work:
var amtBoxes = new[] {
amtBox1,
amtBox2,
amtBox3
}

Categories