I am trying to iterate through two listBoxes for a program I am coding. Both listBoxes will have a different item count inside of it.
Basically, I want my program to get the selectedItem from one listBox and use the string or text from that item to replace the text from EACH and EVERY single item in the other listBox.
Once it's done using the selectedItem from the original listBox for all the items in the other listBox, I want it to go to the next item in the original listBox and do the same process all over again.
It should repeat this UNTIL it has gone through ALL of the items in the original listBox.
Hopefully that made sense....
Here is some example code I made. I created two for loops so that it could iterate through both listBoxes.
for (int i = 0; i < listBoxOriginal.Items.Count; i++)
{
string linkurl = listBoxOriginal.Items[i].ToString() + "..";
listBoxNewListBox.SelectedIndex = 0;
for (int o = 0; o < listBoxNewListBox.Items.Count; o++)
{
string s = listBoxNewListBox.Items[o] as string;
string newurl = s.Replace("DOMAIN", linkurl);
listBoxNewListBox.SelectedIndex++;
}
}
My issue is, when the inner for loop finishes iterating completely it errors out. I know the error is because it reached the end of the listBox and can't go any further, but I don't know how else to iterate through the listBox without having the items selected.
What it should do is, once it reaches the end of "listBoxNewListBox" it should go to the next item in "listBoxOriginal", and perform the same process all over again until it's done going through every item in "listBoxOriginal".
Any help would be appreciated!
I think problem is because of SelectedIndex at list. I think it's just going to far.
Here is a little modification:
for (int i = 0; i < listBoxOriginal.Items.Count; i++)
{
string linkurl = listBoxOriginal.Items[i].ToString() + "..";
for (int o = 0; o < listBoxNewListBox.Items.Count; o++)
{
string s = listBoxNewListBox.Items[o] as string;
string newurl = s.Replace("DOMAIN", linkurl);
listBoxNewListBox.SelectedIndex = o;
}
}
Here is explanation:
When in inner loop you are doing this operation: listBoxNewListBox.SelectedIndex++ you are setting this index as 1 more than index of loop. That means, if we look at very last iteration of inner loop, this index is set with value which is already to high. This is probably reason why application throws an exception.
Related
I have found many examples on how to find the selected items in a listbox and how to iterate through a listbox;
for(int index=0;index < listBox1.Items.Count; index++)
{
MessageBox.Show(listBox1.Items[index].ToString();
}
or
foreach (DataRowView item in listBox1.Items)
{
MessageBox.Show(item.Row["ID"].ToString() + " | " + item.Row["bus"].ToString());
}
While these methods work great for the selected items, what I have yet to figure out, or find, is how to get the selected state, selected and unselected, of every item in a listbox, as the above only gives the selected.
Basically, I need something like this;
for(int index=0;index < listBox1.Items.Count; index++)
{
if (index.SelectedMode == SelectedMode.Selected)
{
MessageBox.Show(listBox1.Items[index].ToString() +"= Selected";
}
else
{
MessageBox.Show(listBox1.Items[index].ToString() +"= Unselected";
}
}
I've found a snippet that said to use (listBox1.SelectedIndex = -1) to determine the selected state however I've not figured out or found how to build a loop around this to check each item in the listbox.
I've also read that I should put the listbox items into an array, but again nothing about getting the selected state of each item in the listbox.
I know I'll have to iterate through the listbox to accomplish what I'm needing, pretty sure it'll be one of the above loops, however I have yet to find how to extract the selected state of each item in the listbox.
I'm using VS2013, C# Windows Form, .NET Framework 4.0
Thanks in advance for any advice/direction.
This will get you the unselected items:
List<string> unselected = listBox1.Items.Cast<string>().Except(listBox1.SelectedItems.Cast<string>());
You can loop over that list like this:
foreach(string str in listBox1.Items.Cast<string>().Except(listBox1.SelectedItems.Cast<string>()))
{
System.Diagnostics.Debug.WriteLine($"{str} = Not selected");
}
I've made the assumption that you're using string as your item type. If you want to use something else then just replace string with your type and it should still work.
You then loop over the unselected items to do whatever you want with them then loop over listBox1.SelectedItems to do whatever you want with the selected ones.
You can use GetSelected method of the ListBox. It returns a value indicating whether the specified item is selected.
For example, the following code, sets the value of selected to true if the item at index 0 (the first item) is selected:
var selected = listBox1.GetSelected(0);
Example
Te following loop, shows a message box for each item, showing the item text and item selection status:
for (int i = 0; i < listBox1.Items.Count; i++)
{
var text = listBox1.GetItemText(listBox1.Items[i]);
var selected = listBox1.GetSelected(i);
MessageBox.Show(string.Format("{0}:{1}", text, selected ? "Selected" : "Not Selected"));
}
I have the below for loop
int listCount = _itemCollection.Count;
//_itemCollection is of type SPListItemCollection
for (int i=0;i<listCount;i++)
{
var item = _itemCollection[i]; // just to prevent changes in all places inside the for loop
if(item['expirydate']>today){
item.delete();
listCount--; //as I am removing 1 item, I am decrementing count
}
}
In this for loop, I am iterating through the items in itemcollection and deleting some of them. i.e item will be removed from itemcollection array and so itemcollection.count will be reduced by 1
This is not deleting the 3rd item every time, when I have 3 items to delete
I am not sure what condition should be used for getting it right
You should go in the reverse order as below and use for instead of foreach as below.
int listCount = _itemCollection.Count;
for (int i = listCount - 1; i >= 0; i--)
{
var item = _itemCollection[i]; // just to prevent changes in all places inside the for loop
if(item['expirydate'] > today){
item.delete();
}
}
You can do something like this:
_itemCollection.RemoveAll(item => item['expirydate'] > today);
This removes all the items that matches the given condition.
To remove item from SPListItemCollection check this documentation
Try this:
int listCount = _itemCollection.Count;
for (int i = 0; i < listCount; i++)
{
var item = _itemCollection[i];
if(item [expirydate] > today)
{
_itemCollection.Remove(item);
listCount--;
}
}
This may fulfill your want. Here you can directly use _itemCollection[i] instead of item.
I hope this may help you. Enjoy coding.
I have a list box and I need to modify the list based on the content. I am trying to do this but it does not do any thing.
string itemRemove = "Apple";
lstFruits.Items.Remove(itemRemove);
The problem is that in a ListBox control, you cant remove an item like you remove them from List<T>(i.e using an enumerator). You have to you have to loop using an index, starting at the last item, like this :
for (int n = lstFruits.Items.Count - 1; n >= 0; --n)
{
string itemRemove = "Apple";
if (lstFruits.Items[n].ToString().Contains(itemRemove))
{
lstFruits.Items.RemoveAt(n);
}
}
What i've tried:
try 1:
for(int x = listBox1.SelectedIndices.Count - 1; x>= 0; x--)
{
int idx = listBox1.SelectedIndices[x];
listBox2.Items.Add(listBox1.Items[idx]);
listBox1.Items.RemoveAt(idx);
}
try 2:
ArrayList tmpArr = new ArrayList();
foreach (object obj in listBox1.SelectedItems)
{
listBox2.Items.Add(obj);
tmpArr.Add(obj);
}
foreach (object obj in tmpArr.ToArray())
{
listBox1.Items.Remove(obj);
}
Also tried everything in the following post: How to remove multiple selected items in ListBox?
Still nothing worked. What am I doing wrong?
var selectedItems = new object[listBox1.SelectedItems.Count];
listBox1.SelectedItems.CopyTo(selectedItems, 0);
foreach (var item in selectedItems)
{
listBox1.Items.Remove(item);
}
or with a bit of LINQ to simplify the code:
foreach (var item in listBox1.SelectedItems.Cast<object>().ToArray())
{
listBox1.Items.Remove(item);
}
The reasoning here is that you get all the selected items and put them into another list first. The original issue is that any change you make to the ListBox will change things like SelectedItems and SelectedIndices. Once you've created an independent array and put the selected items into it, nothing you do to the ListBox will affect that array so you can just enumerate it normally.
listbox1.BeginUpdate();
for (int x = listBox1.SelectedIndices.Count - 1; x >= 0; x--)
{
int idx = listBox1.SelectedIndices[x];
listBox1.Items.RemoveAt(idx);
}
listbox1.EndUpdate();
If you cannot guarantee that every object in the list is unique, then this is the correct way to do it, to ensure that the correct selected items get removed.
If you have multiples of the same object in your listbox, you have to refer to them by "index", otherwise if you remove them by "item" it will remove the first instance of any matching items it finds.
I am in the process of writing a bus route planner which called for replication of the waypoint markers in the list. These were stored as strings, so for example I might have had "w1", "w2", "w3"... "w2" (think of a bus going down a high street, looping round a couple of blocks and then returning down the other side to understand why I have that... I only need waypoint markers in the centre of the road, not in each lane)
If I had selected the last "w2" marker as part of a range and used the selectedItem() method to to remove them, it would have removed the first "w2", not the second one. By using the SelectedIndex() method, it removes based on position, not value, so duplicate values are left safely intact.
I just wanted to add that as I have just been dealing with this very same problem, so saw first hand the problem removing by SelectedItem() caused.
I am trying to remove more items from a combobox but the application is only removing one item at a time.
The combobox has a list of email addresses. I want to remove empty items (""), and those that don't have # inside of text.
Code below only removes one item at a time.
for (int i = 0; i < cmbTo.Items.Count; i++)
{
string st = cmbTo.Items[i].ToString();
if (st == "" || st.IndexOf("#") == -1)
{
cmbTo.Items.RemoveAt(i);
}
}
How can I rewrite this?
Hint: Think about what happens to the i variable when you remove an item
...
When you RemoveAt an item, the item is removed, and every subsequent item moves up one index. Your loop then hits the bottom, where it goes back to the top, increments i, and moves on.
Result? You just skipped an item. If this is the last item in the list, then the loop exists.
Instead, manually decrement i to offset your removal, so that everything works:
for (int i = 0; i < cmbTo.Items.Count; i++)
{
string st = cmbTo.Items[i].ToString();
if (st == "" || st.IndexOf("#") == -1)
{
cmbTo.Items.RemoveAt(i);
i--;
}
}
Your code doesn't work because the moment you remove an item from the collection, the Count() decreases and the for loop exits before going through all the list of items.
You need to first create a list of elements to remove (put them in a temp list) and then iterate through the newly created list calling cmbTo.Items.Remove(currentElement);
When you remove an item from a combobox, the indices of the following items change and your item count will change. Could that account for the behavior you're seeing?
Just do the removal in the opposite direction (i.e. from the end to the front), and you won't need to worry about adjusting i1 when the item is removed:
var items = cmbTo.Items;
int i = items.Count;
while (i > 0) {
--i;
string st = items[i].ToString();
if (st == "" || st.IndexOf("#") < 0)
items.RemoveAt(i);
}
1 Which you currently don't do, so some items that should potentially be removed are skipped, which causes your problem.