removing multiple list items from a listview - c#

So I have created a button that when pressed it deletes the multiple items in the listview. However, I can only seem to make it delete one list item at a time. I know this is badly worded so my code should help explain what I am doing:
private void button2_Click(object sender, EventArgs e) //remove
{
try
{
foreach ( ListViewItem eachItem in listView1.SelectedItems)
{
listView1.Items.Remove(eachItem);
}
task.RemoveAt(listView1.SelectedItems[0].Index); // Remove task from the list "task"
I am trying to make it delete all selected items from my listview as well as my list named "task" However, the line of code above only allows me to delete one selected item from the list at a time.
Any help? Thanks

Try This,
for (int i = task.SelectedItems.Count - 1; i >= 0; i++)
{
if (task.Items[i].Selected)
{
task.Items.Remove(listView2.Items[i]);
}
}

I'm going to assume that your list of tasks is equal, in item count, to your ListView, and that the object in task[0] is the same as ListView.Items[0]. If that is true, remove the item from the task first then remove the item from the ListView
// Removing items from the bottom of the selected items and working your way up
for (int i = listView1.SelectedIndices.Count - 1; i >= 0; i--)
{
task.RemoveAt(listView1.SelectedIndices[i]);
listView1.Items.RemoveAt(listView1.SelectedIndices[i];
}

foreach (ListViewItem eachItem in listView1.Items)
{
listView1.Items.Remove(eachItem);
}

you can only remove one item per line,
you can use the ".ToArray" extension method, if you are enumerating over a changing enumerable.
you should also use the BeginUpdate / EndUpdate function, to speed it up
https://msdn.microsoft.com/library/system.windows.forms.listview.beginupdate%28v=vs.110%29.aspx

Related

Loop through wpf listbox using a for loop instead of a foreach loop

I have a c# wpf listbox and I am trying to get the values from the selected items. I cannot use a foreach loop (every value I find will remove an item from the listbox). But this seems impossible.
What I want is somthing like this:
for (int i = <numberofselecteditems> - 1; i >= 0; i--)
{
string displaymembervalue = listbox.selecteditem[i].displaymembervalue;
}
I have a solution which involve to loop over all the listbox items twice. This is not really an option since it will slow the app too much.
Like I said before, this is NOT the
System.Windows.Forms.Listbox
but the
System.Windows.Controls.Listbox
thank you!!
J.
See the solution here, it is essentially using a foreach in the follolwing fashion:
foreach (var item in listBox1.SelectedItems)
{
// Do what you want here... Console.WriteLine(item), etc.
}
If you really want to do it with a for loop rather than a foreach, then do the following:
for(int i = selectedItems.Count - 1; i >= 0; --i)
{
var item = selectedItems[i];
// Do what you want with item
}
Here is your XAML bound to a Observable collection
<ListBox ItemsSource="{Binding items}"/>
Here is your observable collection of objects
private ObservableCollection<Object> _items;
public ObservableCollection<Object> items{
get{ return _items; }
}
Here is the enumeration over them and the removing of each item
for(int x = 0; x < _items.Count; x++){
_items.Remove(_items.Where(n => n == _items[x]).Single());
//You may have to do a notify property changed on this if the UI Doesnt update but thats easily googled.
//Traditionally it would update. However since you are bound to items Im not sure if it will update when you manipulate _items
}
Create a second list. You still have to iterate twice, but the second iteration is not over the entire list of items.
var items List<ListBoxItem>;
foreach (var item in listbox1.SelectedItems)
items.Add(item);
foreach (var item in items)
listbox1.Remove(item);
Alternatively instead of enumerating twice you can create a copy of the list of objects and then remove the items from the original list while still enumerating.
foreach (var selectedItem in listBox1.SelectedItems.Cast<List>())
{
//remove items from the original list here
}

Clearing Multi-Selected Items From Listbox C#

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.

how to change an item index in listview?

I have a listView and two buttons (UP , DOWN) and i want to move the selected item up or down.
I've thought about swapping between the selected item and the upper one.. but the code i tried .. doesn't make sense because index is readonly.
also mines or sum doesn't owrk .. i can't mess with index at all.
private void btnDown_Click(object sender, EventArgs e)
{
listView1.SelectedItems[0].Index--; // It's ReadOnly.
}
So .. how do i let the user the ability to change a ListViewItem index like how VB let us to change these item index [like in the pic]
thanks in advance ...
You have to remove the selected item first, then re-add it at the new position.
E.g to move the item up one position:
var currentIndex = listView1.SelectedItems[0].Index;
var item = listView1.Items[index];
if (currentIndex > 0)
{
listView1.Items.RemoveAt(currentIndex);
listView1.Items.Insert(currentIndex-1, item);
}
Following is an improvement to M4N answer to handle the re order of an item in the top of the list and make it in the bottom of the list
int currentIndex = listView1.SelectedItems[0].Index;
ListViewItem item = listView1.Items[currentIndex];
if (currentIndex > 0)
{
listView1.Items.RemoveAt(currentIndex);
listView1.Items.Insert(currentIndex - 1, item);
}
else
{
/*If the item is the top item make it the last*/
listView1.Items.RemoveAt(currentIndex);
listView1.Items.Insert(listView1.Items.Count, item);
}
In case of observable collections you are also able to call: .Move(currentindex, newindex);
MSDN

C# On_buttonClick, remove null contents from listbox

How do I setup a button click to remove only null contents from a listbox and keep the listbox populated.
Example:
Work
Files
here
Armor
Result (on_button_click,changes listbox):
Work
Files
here
Armor
Any help always appricated.
You need to loop backwards through the items in the ListBox and remove the items that you don't like.
For example:
for (int i = listBox.Items.Count - 1; i >= 0; i--) {
if (String.IsNullOrEmpty(listBox.Items[i] as String))
listBox.Items.RemoveAt(i);
}
The loop needs to be backwards because otherwise, all of the upcoming indices will move down.
Maybe something like this?
Whoops, as noted, you cannot iterate through a collection and modify it at the same time. Therefore, I present some Frankenstein code:
private void OnButtonClick(object sender, EventArgs e)
{
List<String> removeMe = new List<String>();
foreach(String x in listBox.Items)
{
if (String.IsNullOrEmpty(x))
{
removeMe.Add(x);
}
}
foreach(String x in removeMe)
{
listBox.Items.Remove(x);
}
}

Remove selected rows from multi-column listView

I have a listview with two columns and I'm using a context menu to allow users to remove selected rows. To remove the selected rows, I've tried with the following code but it doesn't work:
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
listView1.SelectedItems.Clear();
}
I suspect this is because the listview has two columns, but I can't figure out a solution to remove selected rows. Removing all rows works with: listView1.Items.Clear();.
The latest example of BeefTurkey looks correct, but he should decrement the variable i after removing a selected item:
for (int i = 0; i < listView1.Items.Count; i++ )
{
if (listView1.Items[i].Selected)
{
listView1.Items[i].Remove();
i--;
}
}
The index of items larger as i is decremented by 1 after the removal. So you should reposition i to match the next not tested item.
while (listBox1.SelectedItems.Count > 0)
{
listBox1.Items.Remove(listBox1.SelectedItem);
}
foreach(ListViewItem lvItem in lvDocument.SelectedItems)
{
lvDocument.Items.Remove(lvItem);
}
This seems to work:
for (int i = 0; i < listView1.Items.Count; i++ )
{
if (listView1.Items[i].Selected)
{
listView1.Items[i].SubItems.Clear();
}
}
Is there any way to remove items and re-order the listView so that there are no empty rows in the middle of other rows?
This seems to be a better solution:
for (int i = 0; i < listView1.Items.Count; i++ )
{
if (listView1.Items[i].Selected)
{
listView1.Items[i].Remove();
}
}
What you can do:
foreach (ListViewItem Item in LstvClients.Items)
{
if (item.Selected)
{
LstvClients.Items.Remove(Item);
}
}
(Yours is better, item.Remove())
I have been using something slightly different then the others to remove all the selected items from a ListView control:
foreach (ListViewItem listViewItem in listView1.SelectedItems)
{
listView1.Items.Remove(listViewItem);
}
I'm not sure how this would match up performance-wise to the other posted methods on large lists, but I think it is a little cleaner looking in cases where that isn't an issue.
This is the correct way to remove all selected items. The method is to always access fist selected item with an index 0 and loop until no more selected items left. You cannot refer to other items inside collection with an absolute index safely since indexes will change as soon as you delete one of the items.
while( listView1.SelectedItems.Count > 0)
{
listView1.Items.Remove(lvFiles.SelectedItems[0]);
}
do
{
this.listView1.CheckedItems[0].Remove();
} while (this.listView1.CheckedItems.Count > 0);
This works better

Categories