C#: For loop not iterating - c#

I have a for loop that for each item in a listbox it will perform a sub. Whats weird is the for loop didnt iterate at all. I had to force it to iterate to the first item but after if finished performing all the subs for that item it just stopped.
How can I make it keep iterating for each item in the listbox?
Heres my code:
listBox7.SelectedIndex = 0;
for (int i = 0; i < listBox7.Items.Count; i++)
{
sub1();
sub2();
listBox1.Items.Add(listBox7.SelectedItem.ToString() + "\r");
while (listBox7.SelectedItems.Count > 0)
{
listBox7.Items.Remove(listBox7.SelectedItems[0]);
}
webBrowser1.Navigate("http://www.google.com");
}

You are most likely removing all of the items in the inner while statement, leaving nothing to iterate on in the second pass.
If your listBox1 contains more than 1 item, an exception will always be thrown on the following line:
listBox1.Items.Add(listBox7.SelectedItem.ToString() + "\r");
because there is no longer a selected item.
This is why exception handling, even if you are just testing something, is critical.
If your goal is to process every item in listBox7, then you can accomplish this by moving the following line:
listBox7.SelectedIndex = 0;
inside the for loop, above the line
sub1();

Related

Taking next item in a listbox (youtube videos) in c#

Just a quick question. How to take a next item in a listbox of c#? Just a simple code to go through the items in a listbox:
for (int i = 0; i < listBox1.Items.Count; i++)
{
axShockwaveFlash1.Movie = (listBox1.Items[i].ToString());
}
But the problem is a last item is showing (youtube videos). How to automatically play next item when the previous ends?
int i = 0;
foreach (var listBoxItem in listBox1.Items)
{
// Do stuff using "var" to represent the listbox item, I believe it comes out as a string.
i++; // Increment i so we know what index we are at in the array.
}
Apologies, I may have misread the question. You wanted to make the next item play when the current item finishes? If so, take a look through the aShockwaveFlash1 object to try find a time remaining variable or similar.
Sorry if the first post wasted your time.

Row Index provided is out of range, even after check

My current code:
Remove()
{
for (int i = 0; i < ConGridView.RowCount; i++)
{
if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
{
ConGridView.Rows.RemoveAt(i);
break;
}
}
}
So what I am trying to call the remove function every time a client disconnect. the function will remove the connection address from the datagridview. It works well when clients are disconnection one by one. However, if 100 connections gets dropped and it tries to remove 100 connections in less than a second, than it errors out saying "Row Index provided is out of range". How should I check for that ?
So far I've tried:
Try, catch.
if (ConGridView.Rows[i] != null), if (i < ConGridView.RowCount)
None of it seem to work so far. I've also got results using (i < ConGridView.RowCount) where i is 26 while RowCount is 24, but the remove at function still activates..
Any idea on this ?
You can't do this. Your code loops through all the rows in ConGridView, but it deletes them as you do. Therefore, at some point you will try to access an item you have deleted, which will cause the error you described.
Probably the best approach it to iterate through the rows in reverse order. This way, deleting a row at the end won't affect when you access rows at the start.
The problem is you initialise your for loop with the current count of rows and then start removing those same rows from the datagridview. At some point your for loop will try to remove a row at an index that is greater than the number of rows left.
Try this instead:
for (int i = ConGridView.RowCount - 1; i >= 0; i--)
{
if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
{
ConGridView.Rows.RemoveAt(i);
break;
}
}
why dont you get the total count to a separate variable and then iterate
Remove()
{
int totalConnections = ConGridView.RowCount;
for (int i = 0; i < totalConnections ; i++)
{
if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
{
ConGridView.Rows.RemoveAt(i);
break;
}
}
}
This issue is becuase you are modifying the collection your are iterating over. It will be better if you use a temporary array and two loops to remove your entries.
Remove()
// You can use an array/list or whatever you want below.
Collection<DataGridViewRow> rowsToDelete = new Collection<DataGridViewRow>();
for (int i = 0; i < ConGridView.RowCount; i++)
{
if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
{
rowsToDelete.Add(ConGridView.Rows[i]);
break;
}
}
// now remove the marked entries.
foreach(DataGridViewRow deletedRow in rowsToDelete)
{
ConGridView.Rows.Remove(deletedRow);
}
When you remove an item from an array, it is reconstructed; shifting the remaining elements up by one to remove the gap of the index you have removed.
1. guybrush threepwood
2. murray
3. elaine
4. Jimmy Gibbs Jr.
If you remove 2. item in here; it becomes this:
1. guybrush threepwood
2. elaine
3. Jimmy Gibbs Jr.
When you are iterating, imagine:
for (int i = 0; i < myArray.Count; i++)
{
if (i == 2) myArray.RemoveAt(i);
}
While running this, when i = 3, the element at 3 has changed, you expect it to be 'elaine' but it is 'Jimmy Gibbs Jr.'. One way to fix this is decrease i by one if we delete it, making sure that i refers to correct value.
for (int i = 0; i < myArray.Count; i++)
{
if (i == 2)
{
myArray.RemoveAt(i);
i--;
}
}
I would go for LINQ in this case, though, everything is easier with that.
myArray.RemoveAll(x => x == "murray");
I've tried all the suggestions posted by everyone here, however, the error was still there.
I've solved the problem using a different way... I've switched to TreeNodeView since that's what I was going to use ultimately. Now I can remove as many connection as i want with:
For each(TreeNode TN in ConTreeView)
{
ConTreeView.Nodes.Remove(TN);
}

C#: ArgumentOutOfRangeException was unhandled by usercode

I have an if statement saying that if a webpage has a certain text to remove the selected item on a listBox and iterate down to the next one.
I made some code but when I try it I keep getting:
ArgumentOutOfRangeException was unhandled by usercode
This is the error in more detail:
{"InvalidArgument=Value of '1' is not valid for
'SelectedIndex'.\r\nParameter name: SelectedIndex"}
This is my code:
listBox1.Items.Remove(listBox1.SelectedItem);
listBox1.SelectedIndex = + 1;
EDIT:
Thanks for all the help guys! I removed the issue by not removing the items and just making it iterate down.
You have to test if the item which you are trying to select acutally exists.
int index = listBox1.SelectedIndex;
listBox1.Items.RemoveAt(index);
If (index < listBox1.Items.Count) {
listBox1.SelectedIndex = index;
}
EDIT: If you want to delete items in a loop, it is a good idea to start at the end, since removing an item changes the position of the following items. Looping upwards would make you skip an item each time you remove an item.
for (int i = listBox1.Items.Count - 1; i >= 0; i--) {
if (listBox1.Items[i].ToString() == "whatever") {
listBox1.Items.RemoveAt(i);
}
}
I'd have to see the full code sample (with the if statement) to know for sure. But it is pretty obvious you are setting the selected item to an index that isn't in the list box.
Be careful, the selectedIndex is zero based, not one based.
MSDN says of your error:
ArgumentOutOfRangeException: The assigned value is less than -1 or
greater than or equal to the item count.
Since the error indicates it is happening when you set the SelectedIndex to 1, I am assuming that you only have a single item in the listbox (index=0) when this code is called.
Since indices are 0-based, setting SelectedIndex to 1 is selecting the second value in the list. I'm guessing it's failing when you have removed all but one of the values and are trying to set SelectedIndex to the second one.
Do you want to select the first item in the listBox? If so the code would be:
if(listBox1.Items.Count > 0) listBox1.SelectedIndex = 0;

Clear all array list data

Why doesn't the code below clear all array list data?
Console.WriteLine("Before cleaning:" + Convert.ToString(ID.Count));
//ID.Count = 20
for (int i = 0; i < ID.Count; i++)
{
ID.RemoveAt(i);
}
Console.WriteLine("After cleaning:" + Convert.ToString(ID.Count));
//ID.Count = 10
Why is 10 printed to the screen?
Maybe there is another special function, which deletes everything?
You're only actually calling RemoveAt 10 times. When i reaches 10, ID.Count will be 10 as well. You could fix this by doing:
int count = ID.Count;
for (int i = 0; i < originalCount; i++)
{
ID.RemoveAt(0);
}
This is an O(n2) operation though, as removing an entry from the start of the list involves copying everything else.
More efficiently (O(n)):
int count = ID.Count;
for (int i = 0; i < originalCount; i++)
{
ID.RemoveAt(ID.Count - 1);
}
or equivalent but simpler:
while (ID.Count > 0)
{
ID.RemoveAt(ID.Count - 1);
}
But using ID.Clear() is probably more efficient than all of these, even though it is also O(n).
`Array.Clear()`
removes all items in the array.
`Array.RemoveAt(i)`
removes the element of ith index in the array.
ArrayList.Clear Method
Removes all elements from the ArrayList.
for more detail : http://msdn.microsoft.com/en-us/library/system.collections.arraylist.clear.aspx
After removing 10 items, ID.Count() == 10 and i == 10 so the loop stops.
Use ID.Clear() to remove all items in the array list.
Use the clear() Method
or
change ID.RemoveAt(i); to ID.RemoveAt(0);
Whenever an element is removed from the collection, its index also changes. Hence when you say ID.RemoveAt(0); the element at index 1 now will be moved to index 0. So again you've to remove the same element (like dequeuing). until you reach the last element. However if you want to remove all the elements at once you can better use the Clear() method.
Your code does:
ID.RemoveAt(0);
...
ID.RemoveAt(9);
ID.RemoveAt(10); \\ at this point you have already removed 10
\\ items so there is nothing left on 10- 19, but you are left with
\\ the 'first' 10 elements
...
ID.RemoveAt(19);
Generally speaking your method removes every second element from the list..
Use ArrayList.Clear instead as other have mentioned.

How can I remove all users in an Active Directory group?

I'm trying to remove all users from an AD group with the following code:
private void RemoveStudents() {
foreach (DirectoryEntry childDir in rootRefreshDir.Children) {
DirectoryEntry groupDE = new DirectoryEntry(childDir.Path);
for (int counter = 0; counter < groupDE.Properties["member"].Count; counter++) {
groupDE.Properties["member"].Remove(groupDE.Properties["member"][counter]);
groupDE.CommitChanges();
groupDE.Close();
}
}
}
The rootRefreshDir is the directory that contains all the AD groups (childDir).
What I'm finding here is that this code does not behave correctly. It removes users, but it doesn't do it after the first run. It does "some". Then I run it again, and again, and again - depending on how many users need to be deleted in a group. I'm not sure why it's functioning this way.
Can someone help fix this code or provide an alternative method to delete all users in a group?
You're looping through the items as you delete them causing the index to skip every other item.
You need to change the inner for loop to loop backwards, like this:
PropertyValueCollection members = groupDE.Properties["member"];
for (int counter = members.Count - 1; counter >= 0; counter--) {
members.RemoveAt(counter);
groupDE.CommitChanges();
groupDE.Close();
}
Your problem is that you're counting upwards... You first remove an item at index 0. Every remaining item then moves to index - 1 in the list. You then remove at index 1, and every remaining item shuffles except for the one you've now left at index 0. Basically: you're only removing half of the items.
Instead of a for loop, try while (groupDE.Properties["member"].Count > 0), and simply remove the item at index 0 each time.
Or if you are using
DirectoryServices.AccountManagement.GroupPrincipal (.NET 3.5+):
This will work as well:
groupPrincipal.Members.Clear();
groupPrincipal.Save();
just use:
group.Properties["member"].Clear();
group.CommitChanges();
This reference in CodeProject should help:
"How To Do (almost) Everything in AD:
http://www.codeproject.com/KB/system/everythingInAD.aspx

Categories

Resources