Hello i am working on some personal project,
I have lots of comboboxes in my project, which names are combobox1,combobox2 etc..
What i am trying to do is, getting combobox.text values respectively and do some work according to this.
Here is my code below;
for (i = 1; i <= geneList.Length; i++)
{
baserequest = "/" + comboBox[i].Text + ".docx";
sources.Add(new Source(new WmlDocument(basesource + geneList[i] + baserequest), false));
baserequest="";
DocumentBuilder.BuildDocument(sources, Path.Combine(tempDi.FullName, "Output.docx"));
}
so that actually not work. I searched but i think i missearching something because all i can get is about iterating through items, but what i want to do is exactly this;
comboBox[i].Text
Thank you very much.
If your comboboxes are named comboBox1, comboBox2 .... then you can't refer to comboBox2 using a syntax like comboBox[2]. This syntax means .. give me the third combobox stored in an array of comboboxes (and that should contain at least 3 elements)
So if you really want to use this syntax you need to create that combobox array somewhere in your code. After the call to InitializeComponent for example
public class Form1: Form
{
// declare the array as a global variable
private ComboBox[] combobox;
public Form1()
{
// Create and initialize all the elements of your form
// according to the properties set in the WinForms Designer
InitializeComponent();
// Choose all the individual comboboxes that you want to use
// inside your loops in the remainder of your code
combobox = new ComboBox[] { comboBox1, comboBox2, comboBox3 };
}
// all the code of your Form1 follows.....
}
A final note: You use a different array to create your loops. This array is named geneList and it should be kept in sync with the combobox array. Meaning the two arrays should have the same number of elements otherwise (if the geneList array is bigger than the combobox one you will get an ArgumentOutOfRangeException). Also array indexing start at index 0 not 1 so the usual loop is created with this syntax
for (i = 0; i < geneList.Length; i++)
Otherwise if you start from 1, as you do now, you skip the first element in the array and the last loop searches for an element that doesn't exist.
Related
I am trying to loop trough something 3 times and change the .text property of 3 element that have the names "label1", "label2" and "label3". I'm trying to add the 1,2,3 to the label but I can't get it to work.
this is what I'm trying to do:
the y is either 1,2 or 3
("label" + y).Text
I think you want this,so I make a simple code of it.
for(int i = 1; i <= 3; i++)
{
Console.WriteLine("label" + i);
}
if I understand correctly - you can do this using reflection:
var temp = (double)typeof(MyClass).GetProperty("label" + y).GetValue(myClassInstance);
if you change the type of MyClass to the class that holds your variable, myClassInstance to an instance of your class and the cast from double to your field type (which I'm guessing is some sort of WPF / Winforms control) you can get the variable by name.
It's important to note that your program will slow down if this is used often.
I am trying to test a specific element from a list, and compare it to a string the user inputs. It is inside an if statement:
if (textboxinput.Text.ToString() == main.steps[current])
In this context, current is an integer equal to 0, and after the if statement is done current++.
this is a new wpf form window that is opened by clicking a button on the MainWindow wpf form. main is instantiated from the MainWindow1 class containing our list:
public List<string> steps = new List<string>();
Whenever I run this code, I receive the argument out of range exception.
In short: I am trying substitute the index of the list with a variable, and it is saying it is out of range.
Still learning c#, and this is probably an easy fix, and it's probably a super obvious rule I'm forgetting, but any help would be appreciated, as the same exception happens on arrays as well.
Here is the event for the button being clicked
int current = 0;
private void buttonanswer_Click(object sender, RoutedEventArgs e)
{
if (textboxinput.Text.ToString() == main.steps[current])
{
textboxoutput.Foreground = Brushes.Green;
textboxoutput.AppendText(textboxinput + Environment.NewLine);
textboxinput.Clear();
}
else
{
textboxoutput.Foreground = Brushes.Red;
textboxoutput.AppendText(textboxinput + Environment.NewLine);
textboxinput.Clear();
}
current++;
}
Make sure that when you're looping current, it is always less than the length of the main.steps array. Remember, if an array contains 5 elements, they are numbered 0, 1, 2, 3, and 4 for example. Most likely you are allowing current to reach the number 5 (or whatever is the size of your array in your particular case). This type of mistake would be what causes an out of bounds exception when working with an array.
I have an array of textboxes in which they change dyanmically depending on what the user types in. Those textboxes contain a number which represents a score of an assignment. Those score are linked to a module object. So if the user has 3 modules; 2 assignments on the first and second module and 3 assignments on the third module; then in total there would be 7 textboxes created for the user to input all their assignment marks.
What I am trying to do is to create a keyup event handler in which it gets the number in typed in by the user, and then dynamically calls a method to display the average of the the module. This is what I have so far. The following method gets called whenever the user types in a character:
public void calculateLevel4Modules(int counter) {
//iterate through modules
//iterate through assignts in that module
//whilst iterating, check tb and set userscore
//after iterating, update overall label with regards to modulecounter
//int assignmentCounter = 0;
//Console.WriteLine("in If statement.. " + counter);
for (int moduleCounter = 0; moduleCounter < requiredLevelList().Count; moduleCounter++)
{
int totalNumberOfAssignmentsInCurrentModule = requiredLevelList().ElementAt(moduleCounter).Assignments.Count;
Console.WriteLine("total number of assignmetns: " + totalNumberOfAssignmentsInCurrentModule);
assignmentCounter = assignmentCounter + totalNumberOfAssignmentsInCurrentModule;
Console.WriteLine("assignment counter: " + totalNumberOfAssignmentsInCurrentModule);
if (counter < assignmentCounter)
{
Console.WriteLine("in If statement.. " + userMarksTBLvl4[moduleCounter].Text);
try
{
int userMark = int.Parse(userMarksTBLvl4[counter].Text);
requiredLevelList().ElementAt(moduleCounter).Assignments.ElementAt(counter).UsersScore = userMark;
double modAvg = requiredLevelList().ElementAt(moduleCounter).getModuleScoreOverall();
moduleOverallLvl4[moduleCounter].Text = modAvg.ToString();
break;
}
catch (FormatException) { break; }
}
else { }
}
it works fine if the user has one module but if the user has two or more, then I get an error in the following line:
requiredLevelList().ElementAt(moduleCounter).Assignments.ElementAt(counter).UsersScore = userMark;
I am getting an out of bounds exception. I know why; its because counter is basically the # of the textbox that was typed into but by me using counter, I am accessing something not within the assignments list. This is an example of when the problem occus:
The user has 2 modules. In each module there are 2 assignments thus 4 textboxes are been created with their index ranging from 0 - 3. If the user wants to type in their score of the first assignment on the second module, its basically trying to write to the third index in that element then it crashes since that module only consist of 2 assignments.
There are some strange things in your code that make it hard to answer. First, the code you posted doesn't compile, so we have no way to test it.
Several times you use code like:
requiredLevelList().ElementAt(moduleCounter)
I assume requiredLevelList is a method that returns a list of things. There is no reason to assume requiredLevelList returns the same list, or even lists with the same number of elements, each time you call it. Maybe it does in your particular case, but this is a dangerous thing to rely on. You should use a construct like:
foreach (var module in requiredLevelList())
{
int totalNumberOfAssignmentsInCurrentModule = module.Assignments.Count;
...
module.Assignments.ElementAt(counter).UsersScore = userMark;
...
}
Code like this:
Console.WriteLine("total number of assignmetns: " + totalNumberOfAssignmentsInCurrentModule);
is symptomatic of trying to debug something after it has crashed. That is extremely inefficient. Learn how to use a debugger; you will not become an effective programmer until you know how to do this.
requiredLevelList().ElementAt(moduleCounter).Assignments.ElementAt(counter).UsersScore = userMark;
You're probably getting an out-of-bounds exception here because counter is outside the indexes of Assignments. Since you never initialize or change counter, I have no way to know what it is or should be. A debugger will tell you this, use one.
the # of the textbox that was typed into but by me using counter, I am accessing something not within the assignments list.
OK, if you're typing something “not within the assignments list” then you have to test for that and decide what to do. Perhaps something like:
if (counter >= 0 && counter < module.Assignments.Count)
module.Assignments.ElementAt(counter).UsersScore = userMark;
else
throw new Exception("I really have no idea what you want to do here.");
This also looks wrong:
moduleOverallLvl4[moduleCounter].Text = modAvg.ToString();
You never tell us what moduleOverallLvl4 is, but here you're assuming it has the same size as what is returned by requiredLevelList(). Maybe they are in this particular case, but that is a dangerous assumption. If these values are related, moduleOverallLvl4 should be contained in whatever class implements requiredLevelList, and you should have a method that assigns getModuleScoreOverall() to the correct element of moduleOverallLvl4.
I'm building a menu in my WinForm app and i was doing something like :
MenuItem[] items = new MenuItem[] { };
And after :
for (int namesIndex = 0; namesIndex < menuNames.Length; namesIndex++)
{
MenuItem item = new MenuItem(menuNames[namesIndex]);
for (int entriesIndex = 0; entriesIndex < menuEntries.GetLength(1); entriesIndex++)
{
item.MenuItems.Add(menuEntries[namesIndex, entriesIndex]);
}
items[namesIndex] = item;
}
And an IndeOutOfRangeException is thrown :
After this annoying exception i modified the array declaration with this :
MenuItem[] items = new MenuItem[] { null };
and everything works like a charm.
And now the question : Does anyone out there knows why the above array declaration works, and the other doesn't?
Thanks alot
You're using array initializers to construct the array, so the length of the array will be given by the data you provide.
The first example declares an array with a length of zero as you don't provide any elements. I.e. it cannot contain any elements.
The second example declares an array of length one.
MenuItem[] items = new MenuItem[] { };
This creates an array with 0 items in it.
MenuItem[] items = new MenuItem[] { null };
This creates an array with 1 item in it (it's null, but that still counts).
You probably want to initialize for the number of items you want (new MenuItem[menuNames.Length], for example). Or use new List<MenuItem>() instead, and call Add().
"Everything works like a charm" only to the extent that menuNames has exactly one item. You need to change the code as follows to make it work:
MenuItem[] items = new MenuItem[menuNames.Length];
The reason you saw a crash in the first case is that you created an array with zero items, while in the second case you created an array with one item. If menuNames has more than one element, your code would start crashing again.
Your for loop iterates over compares the loop variable to menuNames.Length, while your using the indexer of the items array. One of the two is wrong.
Additionally, if you want to be adding additional items to a collection, then you should almost certainly be using a List, not an array.
I have multiple XAML TextBoxes, each of which manipulate a corresponding value in an array, when the value in the TextBox is changed, using a C# method which dynamically checks which TextBox has called the method.
<TextBox x:Name="_0_0" TextChanged="_x_y_TextChanged"/>
<TextBox x:Name="_0_1" TextChanged="_x_y_TextChanged"/>
<TextBox x:Name="_0_2" TextChanged="_x_y_TextChanged"/>
// And so on.....
each of which manipulate a corresponding value in an array, when the value in the TextBox is changed, using a C# method which dynamically checks which TextBox has called the method.
private void _x_y_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox current = (TextBox)sender;
string currentname = current.Name;
string rowstring = currentname.Substring(1, 1);
string columnstring = currentname.Substring(3, 1);
int row = Convert.ToInt32(rowstring);
int column = Convert.ToInt32(columnstring);
// I've then detected the name of the textbox which has called it...
So this information can be used to dynamically store information from a TextBox in a corresponding array index - or whatever you want to do with it...
My question however, is:
How can I create a method which uses index locations in my array, to call the relevant TextBox and update its text?
Use FindName(string) to find the text box by name as follows (where container is a control that contains all of the text boxes):
private void UpdateTextBox(int row, int column, string text)
{
TextBox textBox = container.FindName("_" + row + "_" + column) as TextBox;
if(textbox != null)
{
textbox.Text = text;
}
}
There are two ways you might go:
If you have a lot of data to manage, or if you can't predict the length of the array, it would be better to bind to a collection instead of manually poking data into and out of an array. If you create a class derived from ObservableCollection instead of using an array the data <> ui relationship is pretty trivial.
if you really need to do this manually, maybe it would be better to stick the index into the 'tag' field of your text boxes. You could (a) see it clearly in your xaml, (b) parse it easily and (c) if you used a variation on the formula here:
Find all controls in WPF Window by type
you could iterate over the textboxes in window and find the right one by looking at its tag index:
foreach (TextBox t in FindVisualChildren<TextBox>(this))
{
if ((int) t.Tag) == my_index )
{
t.Text = "my_text_goes_here";
}
}
I would go in the direction of the answer I gave on this question:
form anchor/dock
In short, I would create a class that holds the actual values and then create a collection that holds information classes.
Then I would not use the event "TextChanged" on the TextBoxes, rather "sniff" for changes on the Dependency Property used to hold the text. This can easily be done in the Dependency Property.
Last, I would use an ItemsControl or ItemsPresenter to show the controls. Number of controls will follow number of items in the collection.
I suggest using MVVM pattern, data template, and ItemsControl for handling this problem effectively.