3

I have a listView1 in C# WinForms which displays 2 List

List<string> pths;
List<string> rec;

public void Disp ()
        {

            DisplayListInColumns(listView1, pths, 0);
            DisplayListInColumns(listView1, rec, 1);
        }
private static void DisplayListInColumns(ListView listView, List<string> values, int columnIndex)
        {
            for (int index = 0; index < values.Count; index++)
            {
                while (index >= listView.Items.Count)
                {
                    listView.Items.Add(new ListViewItem());
                }
                ListViewItem listViewItem = listView.Items[index];
                while (listViewItem.SubItems.Count <= columnIndex)
                {
                    listViewItem.SubItems.Add(new ListViewItem.ListViewSubItem());
                }
                listViewItem.SubItems[columnIndex].Text = values[index];
            }
        }

I am using the global List to make the changes and also display it in the listview1 but only after the user clicks apply_button will the changes be saved (on to a xml).

The Edit and Add details button is working fine and displaying perfectly. But when I delete the data, I am thrown an error.

The following is the delete action:

//Configuration - DELETE button
        private void button6_Click(object sender, EventArgs e)
        {
            string select = null;

            if (listView1.SelectedItems.Count > 0)
            {
                select = (listView1.SelectedItems[0].Text);
            }
            int count = listView1.SelectedItems[0].Index;

            if (select != null)
            {
                pths.RemoveAt(count);
                rec.RemoveAt(count);
                string s = String.Join("; ", pths.ToArray());
                string r = String.Join("; ", rec.ToArray());
                //MessageBox.Show(s);
                //MessageBox.Show(r);                                
            }
            Disp();
        }

I think after few tries, I am going wrong with the index. Even after deleting, while debugging I get the listView.Items.Count = 5. I am guessing the count is still 5 (sample - 5 string within the list) when after deleting it should reduce to 4 and the index 0-3 accordingly. I am getting the following eror

ArgumentOutOfRangeException at pths.RemoveAt(count)
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

As an alternate I tried pths.Remove(select); but did not resolve this.

Any help would be appreciated. Thank you

leppie
  • 115,091
  • 17
  • 196
  • 297
Vivian Lobo
  • 583
  • 10
  • 29
  • You hope that the index in the ListView matches the index in the List<>. That stops working when you remove an item. Since you remove it from the List<> but not the ListView. So eventually "count" is going to be larger than the last index in the List<>. Kaboom. – Hans Passant Mar 27 '13 at 18:47
  • Thank you @HansPassant I understood the error, just confused about a proper solution. – Vivian Lobo Mar 27 '13 at 19:04
  • It isn't clear to me why you leave a deleted item in the ListView. Removing it as well will be the simple solution. If you need to leave it in then you'll also need a dictionary that maps listview items to list items. – Hans Passant Mar 27 '13 at 19:10

3 Answers3

2

Change your if statement

if (select != null)

to this

if(!string.IsNullOrWhiteSpace(select))

Your text property won't be null, it will be empty string and so you are entering that section when you think you aren't.

EDIT:

Based on your comments, i'm going to direct you to this solution instead, replace your entire delete function with something like this:

private void button6_Click(object sender, EventArgs e)
{
  foreach (ListViewItem eachItem in listView1.SelectedItems)
  {
    listView1.Items.Remove(eachItem);
    if (pths.Any(o => o == eachItem.Text))
    {
        pths.Remove(eachItem.Text);
    }
    if (rec.Any(o => o == eachItem.Text))
    {
        rec.Remove(eachItem.Text);
    }
  }
}

You may need eachItem.Value instead, but I think .Text will work.

NOTE: This answer I absolutely just copied from here (I take no credit for this solution):

Remove the Selected Item From ListView

Community
  • 1
  • 1
Mike C.
  • 3,024
  • 2
  • 21
  • 18
  • I changed the if statement: Initially the List showed and after I delete the first item The last item is a copy and the whole list is just shifted up. – Vivian Lobo Mar 27 '13 at 19:02
  • Delete only the selected items. User selects a single item (I have disabled multiselect) and clicks delete. The selected item should be deleted from the list and similarly be updated in the listview. The Disp() just iterates through the list displaying the contents – Vivian Lobo Mar 27 '13 at 19:22
  • just saw it, tried it and realized... pths is a list. SelectedItems work only for listView. – Vivian Lobo Mar 27 '13 at 19:38
  • That makes it even easier. CHeck the update. You just need to iterate the selected items in your listview. – Mike C. Mar 27 '13 at 19:41
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/27036/discussion-between-vivian-lobo-and-mike-c) – Vivian Lobo Mar 27 '13 at 19:43
1

You need to verify your SelectedItem first before trying to remove it from the List.

   private void button6_Click(object sender, EventArgs e)
    {
        string select = (listView1.SelectedItems.Count > 0) ? (listView1.SelectedItems[0].Text) : null;
        if (!string.IsNullOrWhiteSpace(select))
        {
            listView1.BeginUpdate();
            pths.Remove(select);
            rec.Remove(select);
            listView1.EndUpdate();

            string s = String.Join("; ", pths.ToArray());
            string r = String.Join("; ", rec.ToArray());                     
        }
        Disp();
    }
d.moncada
  • 16,900
  • 5
  • 53
  • 82
  • I tried this solution as well, I am able to remove the item fromt he List which is the pths and rec, because when testing I display string s and r and it gives me the list deleting the selected item. Just that the listview is not updating properly. – Vivian Lobo Mar 27 '13 at 19:03
  • Updated the solution... What collection is your ListView using? (pths or rec) also, how is it not updating properly? – d.moncada Mar 27 '13 at 19:12
  • It is a collection of strings. `List pths = new List(xml.xmlreader("C:\\product.txt", "Name")); List rec = new List(xml.xmlreader("C:\\product.txt", "Recurse"));` – Vivian Lobo Mar 27 '13 at 19:22
  • sorry @moncaded The updated solution did not work as well, if you need any further information from the form I can paste it. – Vivian Lobo Mar 27 '13 at 19:26
  • Shouldnt you only update the Display whenever an item is deleted? Try moving Disp() after string.join (inside the if check). – d.moncada Mar 27 '13 at 19:31
0

Sounds like you just need to reload your list...

//Clear it
listView1.Items.Clear();
//reload it.
listView1.Refresh();
Winderps
  • 100
  • 9