im just started learning c# and i have this little thing.
i dont really know how to call it but here it goes:
there are like 5 textboxes, and i want to set the value of each textblock with a for loop.
they are called t_1, t_2, t_3 and so on.
for (int i=0; i<5; i++)`
{
("t_" + i).Text = i;`
}
this gives this error:
Error 1 'string' does not contain a definition for 'Text' and no
extension method 'Text' accepting a first argument of type 'string'
could be found (are you missing a using directive or an assembly
reference?)
while the textboxes do have .Text properties.. what am i missing?
(btw im using MS VSExpress 2012 for windowsphone)
thanks in advance :)
EDIT:
thank you all very much for all the effort! :D
you guys really helped me out, and im back on track learning! :D
I'm afraid that you can do that so directly. Create a list of your textboxes like
var list = new List<TextBox> { t_1, t_2, t_3, t_4, t_5 };
and then you will be able to do
for (int i=0; i<5; i++)
{
list[i].Text = i.ToString();
}
I also advise you to replace
for (int i=0; i<5; i++)
with
for (int i = 0; i < list.Count; i++)
so that you can just add new controls without having to change the loop.
EDIT:
Sudhakar answer is also a usable solution, but to clarify benefits of my, here are the facts:
using literals in code is a way to earn a nice bug ... imagine more devs working in the same solution and one of them changing a name of a component so that it better express its purpose
code readability - list[i].Text = i; versus reference boxing and Find("t_" + i,true)[0] ... a fairly significant difference in readability
The Textboxes are Properties of an overlying object, maybe a ASP.Net WebPage, XAML or WinForm.
To be able to itereate through them you have to look at that object first, and change its structure so that the Textboxes are in an enumerable list.
I would suggest a dictionary with string indexers, probably fits you most.
You can't call a variable like a value.
Use this:
for (int i=0; i<5; i++)
{
if (i==1) t_1.Text = i.tostring()
else if (i==2) t_2.Text = i.tostring()
... so on
}
Related
For a university project I was tasked with creating a crossword game in windows forms using c#, I have 25 textboxes laid out in a grid and named with their indexes(e.g. txtCell00, txtCell01).
Image of the form layout with the textbox names and layout
To check the guesses I want to loop through all the cells and compare them to an array of the correct answers, but I don't know how to loop through all the cells without having 25 nested if statements. I wanted to know if there was a way to use string manipulation in the actual code
e.g.
for(int i = 0; i <= 4; i++)
{
for(int m = 0; m <= 4; m++){
if(txtCell[i][m].Text == ans[i][m])
{
}
}
}
I am probably being stupid and there is probably a better alternative so I would greatly appreciate any help you could give.
Let's suppose we have a List collection A and an int array B. Now we need to see, independent of order, which elements from the array B are present in collection A. Add the elements that are missing and delete the elements that are not to be found int array B.
I have done this using the code below :
for (int i = 0; i < A.Count; i++)
{
for (int k = 0; k < B.Length; k++)
{
if (A[i] == B[k]) goto Found;
}
A.RemoveAt(i);
Found: continue;
}
for (int i = 0; i < B.Length; i++)
{
for (int k = 0; k < A.Count; k++)
{
if (A[k] == B[i]) goto Found;
}
A.Add(B[i]);
Found: continue;
}
Is there a faster way to achieve the same result? Notice that I cannot just delete A and create a new one in accordance with B because this is just a simplified example.
It's futile, in the end you will get collection B all over again. just create collection A based on array B. simple as that!
The very short (and fairly fast) version would be
A.Clear();
A.AddRange(B);
but perhaps you don't really want that either. You can shorten your code a bit when using the Contains method, though:
for (int i = A.Count; i >= 0; i--) {
if (!B.Contains(A[i])) {
A.RemoveAt(i);
}
}
foreach (var item in B) {
if (!A.Contains(item)) {
A.Add(item);
}
}
The first loop cannot be a foreach loop because A is modified while it is being iterated over. It also runs backwards to ensure that every item is looked at.
However, this has quadratic runtime (more precisely: O(|A| · |B|)) and can get slow rather quickly (pun not intended) with large lists. For better runtime (albeit higher memory requirements) you may need to use HashSets for the Contains tests requiring only O(|A| + |B|) runtime performance at the cost of O(|A| + |B|) more memory.
This is a quite long-winded way of getting to the point, though: If you don't care about order of your items, then it seems like your lists are more like sets. In that case, a set data structure makes more sense because it can do those operations efficiently. And you apparently don't care about element order, because you're just adding missing items at the end anyway.
I think using LINQ should be fast:
A.RemoveAll(tmp => !B.Contains(tmp));
A.AddRange(B.Where(tmp => !A.Contains(tmp)));
EDIT: as pointed out by Joey this is still only O(|A| · |B|).
OK I will give you some more details. The example I set above was oversimplified. What I actually have is an XML file which is loaded on an XElement. There are child nodes with specific attributes mapping precisely to the properties of a custom type in my application. Every child node creates an instance of the aforementioned type.
For purposes of extensibility, if I need to add a new property to the custom type, I want all records in the XML file to be updated with the new attribute with an empty value. And if I delete a property, I want the opposite. So here, I must check the collection of Attributes towards the PropertyInfo[] of the custom type. I cannot delete all of the Attributes and recreate them again because their values will be lost as well.
In my approach, I could see that some checks were done twice and because I am really novice, I thought that maybe this was a casual issue that is dealt with a way I could not think of. Thank you all for the nice replys.
I am trying to learn how to make graphs and populate them using a data list I cal from my class. I made a method to read all my Scale values then I call it to my form. After doing research I found one that looked promising so I modified it to work for me. Upon completion I received the following errors and after looking it up I'm still not sure why. Is there a better way of filling my chart with points using a list and or how can I salvage this one. Thank you in advance.
errors:
cannot convert from 'System.Windows.Forms.DataVisualization.Charting.DataPointCollection' to 'WindowsFormsApplication1.Class1'
The best overloaded method match for 'System.Collections.Generic.List.Add(WindowsFormsApplication1.Class1)' has some invalid arguments
Method I am using:
List<Class1> points = new List<Class1>();
for (int i = 0; i < 100; i++)
{
points.Add(new DataPoint(i, 1));
}
points.Clear();
May i ask if the following code i wrote is correct? Basically, i want to create an 2D array, and within each array, i want to have a list of vertices. So if tCount and pCount is 10, i would have 100 different lists storing vertices. The adding of the vertices will be done elsewhere after certain operations are done to determine which list the vertice should be added to.
List<Vertice>[,] lists = new List<Vertice>[tCount, pCount];
for (int i = 0; i < tCount; i++) {
for (int o = 0; o < pCount; o++) {
lists[i,o] = new List<Vertice>(); } }
Pardon me for posting such a simple question, because i have posted a similar qns in another forum and the replies i received kind of confused me. But thanks for reading!
Mitch Wheat- There was no error so far, but i am also not sure if the list is created properly..
Damith- I've seen that before but i do not really understand the code, so i was wondering if the code i typed was correct or not. I feel safer using a code that i understand, although i do understand the benefits of using a 1-liner.
Oberdan Nunes- I need it to be in a 2D array, as it is related to another 2D array of data which i have.
Okay, I have this piece of code:
int arrPanelsRequired = 4;
string airport;
int arrPanelsMade = 0;
for (; arrPanelsMade <= arrPanelsRequired; arrPanelsMade++)
{
Panel arrPanelXXX = new Panel();
and I need to replace the XXX with the value of arrPanelsMade. I found several ways to name an object after a variable's value, however, I wasn't able to apply any of them here :(
I don't think it would be a good idea in general, let alone in C#. I can see many arr prefixes, which leads me to the use of an array. I think you might be looking for something like this:
int arrPanelsRequired = 4;
Panel[] panels = new Panel[arrPanelsRequired];
for (int arrPanelsMade = 0; arrPanelsMade < arrPanelsRequired; arrPanelsMade++)
{
panels[arrPanelsMade] = new Panel();
}
What you are trying to do is bad practice. It passes in weakly-typed languages, but in strongly-typed languages such as C#, variables need to be explicitly declared. This helps the compiler to catch errors that can be caused by typos or general development mistakes. For example, if you have a variable arrPanel089, how can you/the compiler know if it has been declared? Strong typing can seem like a constraint when coming from weakly-typed languages, but it is really a great tool that saves you a ton of headache as the developer.
If you want to create a set of panels, store them in an array/list/etc and access them by their index. If you want to give them a key, store them in a dictionary which allows you to access values by key instead.
You should add the panels to a List or array, and access them later by index:
arrPanel = new Panel[arrPanelsRequired];
for( int idx = 0 ; idx < arrPanelsRequired ; idx++)
arrPanel[idx] = new Panel();
You have a couple of things going on here that raise red flags. I'll digress from your question just a bit, because I think you're probably going down the wrong road in a couple of respects.
Drop the "arr" prefix, and just call your variables what they are — don't try to emulate Hungarian Notation unless you've got good reason to do so.
Consider using a while loop instead of a for loop if you're not going to perform your initialization in the loop header.
Now on to your question. No, the language doesn't work like that. Use a List<Panel> class instead. That will allow you to add more panels dynamically without having to predefine how many you want, such as in an array.