Search code examples
c#listviewselecteditemlistviewitem

Listview selected item value - not Index


I am working on a project (simple phone book) for personal use. This is how it looks like:

I have a listview filled with contacts and everything was working perfectly untill I added this line of code, when everything became messed up.

listView1.Sorting = SortOrder.Ascending;

So, the problem is obvious. Let's say that there are 6 contacts in the list, and Contact 1 lives in City 1, on Address 1, has a Tel. No 1 [etc], and Contact 2 lives in City 2, on Address 2, has a Tel. No 2 etc. [...sequence continues...]

When I try to make some changes, for example, Contact 5 suddenly gets the information of other contact, in this case, Contact 7. It doesn't matter whose information it gets though, the matter is that everything becomes messed up.

Also, if i want to delete all the contacts from the listview - it is not possible - there will always be one remaining. For example, if there were 6 of them, 5 would be deleted and there would be one left. Also, if there was 100 of them, it would delete 99 and the one would always remain as well.

I figured out that there is no sense to use index of selected item anymore and that I have to use value of the selected item now (instead of its index). But, the problem is I do not know how to do that.

Maybe it comes to listView1_SelectedIndexChanged only. Please note that i am just taking a guess, I am not completely sure.

If so, here is the code:

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (listView1.SelectedItems.Count == 0) return;
        textBox1.Text = people[listView1.SelectedItems[0].Index].Name;
        textBox2.Text = people[listView1.SelectedItems[0].Index].Hometown;
        textBox3.Text = people[listView1.SelectedItems[0].Index].Address;
        textBox4.Text = people[listView1.SelectedItems[0].Index].Phone;
        textBox5.Text = people[listView1.SelectedItems[0].Index].Email;
        textBox6.Text = people[listView1.SelectedItems[0].Index].AdditionalInfo;
        dateTimePicker1.Value = people[listView1.SelectedItems[0].Index].Birthday;
        textBox1.ReadOnly = true;
        textBox2.ReadOnly = true;
        textBox3.ReadOnly = true;
        textBox4.ReadOnly = true;
        textBox5.ReadOnly = true;
        textBox6.ReadOnly = true;
        dateTimePicker1.Enabled = false;
        toolStripButton5.Enabled = true;
    }

I think the code is to big to upload it here, so I uploaded the code here:

Does anyone have a solution?


Solution

  • In order to find the right object to update you first need to find the object in the People collection that matches the object selected in the ListView.

    Person i = People.FirstOrDefault(p => p.Name == ((ListView) sender).SelectedItems[0].Text);
    PopulateEditData(i); // refer below for method...
    

    This can only work if you have the MultiSelect property set to false, otherwise you will need to get the right item from the collection of selected items.

    As seen here: http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.selecteditems(v=vs.110).aspx

    Once you have the right Person object, you will be able to retrieve and display the objects details in the text boxes:

    private void PopulateEditData(Person selectedPerson)
    {
        textBox1.Text = selectedPerson.Name;
        textBox2.Text = selectedPerson.Hometown;
        textBox3.Text = selectedPerson.Address;
        textBox4.Text = selectedPerson.Phone;
        textBox5.Text = selectedPerson.Email;
        textBox6.Text = selectedPerson.AdditionalInfo;
        dateTimePicker1.Value = selectedPerson.Birthday;
        textBox1.ReadOnly = true;
        textBox2.ReadOnly = true;
        textBox3.ReadOnly = true;
        textBox4.ReadOnly = true;
        textBox5.ReadOnly = true;
        textBox6.ReadOnly = true;
        dateTimePicker1.Enabled = false;
        toolStripButton5.Enabled = true;
    }
    

    I would also suggest setting the selectPerson as a property of your form or one of the classes available to it so it is a little easier to edit and save the data on the object.

    For the removal part of the problem, use the SelectedPerson property for the item to be removed.

    private void button1_Click(object sender, EventArgs e)
        {
            if (SelectedPerson != null)
            {
                People.Remove(SelectedPerson);
                this.listView1.Items.Clear();
                foreach (var person in People)
                {
                    this.listView1.Items.Add(person.ToString());
                    this.listView1.Sorting = SortOrder.Ascending;
                }
                this.listView1.Refresh();
                this.button1.Enabled = false;
            }
        }