C# How to programmatically build property name [duplicate] - c#

This question already has answers here:
Get property value from string using reflection
(24 answers)
Closed 7 years ago.
I have an object called "Agent". Agent has among others, 10 properties named lab1 thru lab10. I need to assign these properties to text boxes on a form txtFieldLabel1 thru txtFieldLabel10. In the example below the left side of the operator in the loop is fine. I can't figure out the right side. I need to dynamically build the property name based on the index of the loop. This seems it should be fairly simple and similar to the left side of the operator.
for (int i = 1; i <= 10; i++)
{
tlp.Controls["txtFieldLabel" + i.ToString()].Text = Agent.lab + i.ToString();
}

Agent.GetType().GetProperty("lab" + i).GetValue(Agent, null);
That will get the value of the property that, using reflection, is defined as labX, where X is the value of i.
Edit: changed to GetValue(Agent, null) instead of GetValue(Agent), as the overload for the single object parameter was introduced in .NET 4.5.

You could use reflection as others mentioned, but it would be easier if you created Dictionary<int, string> inside your Agent class and define those KeyValuePairs with keys from 1 to 10 and desirable values corresponding to those keys. Here is an example:
public class Agent
{
public Dictionary<int, string> Lab = new Dictionary<int, string>();
public Agent()
{
this.Lab.Add(1, "Value 1");
this.Lab.Add(2, "Value 2");
this.Lab.Add(3, "Value 3");
// ...
this.Lab.Add(10, "Value 10");
}
}
Then you could call it like this:
var agent = new Agent();
for (int i = 1; i <= 10; i++)
tlp.Controls["txtFieldLabel" + i].Text = agent.Lab[i];

This seems it should be fairly simple and similar to the left side of the operator.
It's not simple at all; you can do it using reflection, but that's pretty advanced programming.
I suspect there are more meaningful property names available to you than lab1, lab2, etc. and strongly recommend you use them. Anyone who has to come back to this code in a few months will be grateful.

You can get the properties' values using reflection:
var agent = new Agent();
//...
var value = agent.GetType().GetProperty("lab" + i).GetValue(agent);
(Note: Agent is the class-name, while agent is the variable/instance)
Another (better/cleaner?) solution might be to implement the lab-properties as an array or List<string>, e.g:
class Agent {
public List<string> Labs {get;set;}
}
Then you could iterate over all Labs:
for (var i=0; i<agent.Labs.Count; i++) {
tlp.Controls["txtFieldLabel" + (i+1)].Text =
agent.Labs[i];
}

Related

Does expanding arraylist of objects make a new object?

Assume we have an array list of type Employe , does expanding it's length by 1 make a new object in the list ?
is the code in else statement correct? and is it recommended?
public void ModifierEmp(int c)
{
for(int i = 0; i < Ann.Count; i++)
{
if(Ann[i].Code == c)
{
Ann[i].saisie();
} else
{
i = Ann.Count + 1; //expanding arraylist ann
Ann[i].saisie(); //saisie a method for the user to input Employe infos
}
}
}
https://imgur.com/VfFHDKu "code snippet"
i = Ann.Count + 1;
The code above is not expanding the list: it is only setting your index variable (i) to have a new value.
If you wanted to make the list bigger, you would have to tell it which object to put into that new space you create. For example:
Ann.Add(anotherItem);
Of course, this gives you the ability to decide whether to add an existing item, create a new item (e.g. Ann.Add(new Something() { Code = c })), or even add a null value to the list (which is not usually a good idea).

Getting "No overload for method 'Add' takes 2 arguments" [duplicate]

This question already has answers here:
How can I add an item to a ListBox in C# and WinForms?
(9 answers)
Closed 4 years ago.
I have a function for a Windows form application where I'm retrieving the list of files in a folder and I'm stripping out a "part number' contained within each file name. I'm then adding the part number and the file name to a listbox.
Everything works fine when I use the code.
lstProcessedParts.Items.Add(lsPartNumber);
If I change the code to add the value for the listbox item, I get the error.
lstProcessedParts.Items.Add(lsPartNumber, lsFilename);
Here is my function.
public void LoadPartNumberList()
{
string lsFilename, lsPartNumber = "";
int liPartNumberStartPosition, liPartNumberEndPosition, liPartNumberLength = 0;
string[] files = Directory.GetFiles(txtFolderSelected.Text);
foreach (string pathandfile in files)
{
lsFilename = Path.GetFileName(pathandfile);
liPartNumberStartPosition = lsFilename.IndexOf("-") + 1;
liPartNumberEndPosition = lsFilename.IndexOf("-", liPartNumberStartPosition + 5);
liPartNumberLength = liPartNumberEndPosition - liPartNumberStartPosition;
lsPartNumber = lsFilename.Substring(liPartNumberStartPosition, liPartNumberLength);
lstProcessedParts.Items.Add(lsPartNumber, lsFilename);
}
}
Can anyone help me fix my code so this works?
I can't answer definitively because I can't see enough of your system, but...
If you need a different display member and value member in your Items you should add instances of a custom Type to the List and make sure you configure the display and value members accordingly.
So, if you have class:
class ProcessedPart
{
public string PartNumber {get; set;}
public string FileName {get;set;}
}
Now you can Add instances of ProcessedPart to the list:
lstProcessedParts.Items.Add(
new ProcessedPart {
PartNumber = lsPartNumber,
FileName = lsFilename
});
Be sure to configure the list
lstProcessedParts.DisplayMember = "PartNumber";
lstProcessedParts.ValueMember = "FileName";
... or which ever way you need it

c# collections and re-numbering not working as expected

Hi i'm trying to setup simple test data.
I simply want to take a collection which is smallish and make it bigger by add itself multiple times.
After I;ve added them together i want to re-number the property LineNumber
so that there are no duplicates and that it goes in order. 1,2,3,4....
no matter what i try it doesn't seem to work and i cant see the mistake.
var sampleTemplateLine = dataContext.TemplateFileLines.ToList();
*//tired this doesnt work either*
//List<TemplateFileLine> lineRange = new List<TemplateFileLine>();
//lineRange.AddRange(sampleTemplateLine);
//lineRange.AddRange(sampleTemplateLine);
//lineRange.AddRange(sampleTemplateLine);
//lineRange.AddRange(sampleTemplateLine);
var allProducts = sampleTemplateLine
.Concat(sampleTemplateLine)
.Concat(sampleTemplateLine)
.Concat(sampleTemplateLine)
.ToList();
int i = 1;
foreach (var item in allProducts)
{
item.LineNumber = i;
i++;
}
this doesnt seem to work either
//re-number the line number
var total = allProducts.Count();
for (int i =0; i < total; i++)
{
allProducts[i].LineNumber = i+1;
}
PROBLEM: below RETURN 4 when i'm expecting 1
var itemthing = allProducts.Where(x => x.LineNumber == 17312).ToList();
You are adding the same objects multiple times. You wold have to add new objects or clone the ones you have.
The problem is they are pointing the same object. So if you change a property it changes all the pointed objects at the same
You can use Clone method if it exist, if not you can create your own Clone method like in this question.

Getting a string to be a variable name

I found this question but it's being used with an XML file so I don't really understand what is going on.
What I want to do is get my list of objects to get populated in my for loop. Right now I have this:
for (int i = 0; i < dogs.Length; i++)
{
dogs[i] = new Dog();
}
dogs[0].PictureBox = picDog0;
dogs[1].PictureBox = picDog1;
dogs[2].PictureBox = picDog2;
dogs[3].PictureBox = picDog3;
I want to do something like this:
for (int i = 0; i < dogs.Length; i++)
{
dogs[i] = new Dog();
dogs[i].PictureBox = StringToVariable("picDog" + i);
}
PictureBox is a property field in case that makes a difference.
StringToVariable() is the thing I don't know about. I don't even know what it would be called to search for it.
It's impossible to say for sure without a good, minimal, complete code example. But I would expect that the following statement should work in your scenario:
dogs[i].PictureBox = (PictureBox)Controls.Find("picDog" + i, true)[0];
That will search the children of the current control (which I assume in this case is your Form subclass) for each control in turn. This is somewhat inefficient, as it has to search the controls collection for each item, but as long as you have a relatively small number of items, this is likely not a problem.
Depending on how your Form is set up, the following might also work:
string prefix = "picDog";
foreach (PictureBox pictureBox in Controls.OfType<PictureBox>())
{
if (pictureBox.Name.StartsWith(prefix))
{
int index;
if (int.TryParse(pictureBox.Name.Substring(prefix.Length), out index))
{
dogs[index] = pictureBox;
}
}
}
That version inspects each child control just once, attempting to parse an index appended to the initial text of "picDog", and if it's successful, using that index to assign to your array directly. This has the advantage of scaling well to larger lists of controls, but may be overkill in your case.
Note that in both of the above examples I've left out any error checking. In either example, you would probably want to add some kind of handling in case (for the first example) the desired control couldn't be found, or (for the second example) if you find a control for which you can't parse the index, or fail to fill in one of the elements of the dogs array.
If for some reason neither of the above examples seem to work for you, please edit your post so that it includes a better code example.
Sometimes a simple solution can work well. How about this?
var picDogs = new [] { picDog0, picDog1, picDog2, picDog3 };
for (int i = 0; i < dogs.Length; i++)
{
dogs[i] = new Dog();
dogs[i].PictureBox = picDogs[i];
}
You could even do this:
var dogs = new [] { picDog0, picDog1, picDog2, picDog3 }
.Select(picDog => new Dog() { PictureBox = picDog })
.ToArray();

Access dynamic object by name in a loop

I am new to c# as am a php / js / html developer.
I have 8 switches named relay_1,relay_2,relay_3 etc etc
I need to be able to change the state of these but I would like to do through a for loop so the number is dynamic.
I have tried various methods but to no avail.
Any help would be greatly appreciated.
This is what I would like ( not correct )
for (int i = 0; i < 8; i++)
{
relay_" + i.IsChecked = true;
}
You cannot generate the name of a variable dynamically, but you can create an array of relay objects (the allRelays variable below), and do your operation in a loop, like this:
var allRelays = new {relay_0, relay_1, relay_2, relay_3, relay_4, relay_5, relay_6, relay_7, relay_8};
foreach (var relay in allRelays) {
relay.IsChecked = true;
}

Categories