Question

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?

Was it helpful?

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;
        }
    }

OTHER TIPS

Thank you for your answer.

Anyway, I have managed to solve the problem in the following way:

1) I have added:

private Person FindPerson(string name)
    {
        return people.Find(x => x.Name == name);
    }

2) I have replaced:

people[listView1.SelectedItems[0].Index] 

with "person", where person is:

Person person = FindPerson(listView1.SelectedItems[0].Text);

where FindPerson is:

private Person FindPerson(string name)
{
    return people.Find(x => x.Name == name);
}

Anyway, I keep getting error when I try to remove the last remaining contact. Even when I try to select it, not just remove it. Here you can take a look what error is about:

IMAGE: http://s24.postimg.org/ls4nak6et/Kruzeri.png

So, this is how it looks like now:

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (listView1.SelectedItems.Count == 0) return;
        Person person = FindPerson(listView1.SelectedItems[0].Text);
        textBox1.Text = person.Name;
        textBox2.Text = person.Hometown;
        textBox3.Text = person.Address;
        textBox4.Text = person.Phone;
        textBox5.Text = person.Email;
        textBox6.Text = person.AdditionalInfo;
        dateTimePicker1.Value = person.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;
    }

and Save button:

private void toolStripButton1_Click(object sender, EventArgs e)
    {
         if (listView1.SelectedItems.Count > 0)
        {
            Person person = FindPerson(listView1.SelectedItems[0].Text); 
            person.Name = textBox1.Text;
            person.Hometown = textBox2.Text;
            person.Address = textBox3.Text;
            person.Phone = textBox4.Text;
            person.Email = textBox5.Text;
            person.Birthday = dateTimePicker1.Value;
            person.AdditionalInfo = textBox6.Text;
            listView1.SelectedItems[0].Text = textBox1.Text;
            textBox1.ReadOnly = true;
            textBox2.ReadOnly = true;
            textBox3.ReadOnly = true;
            textBox4.ReadOnly = true;
            textBox5.ReadOnly = true;
            textBox6.ReadOnly = true;
            dateTimePicker1.Enabled = false;
        }
        else
        {
            MessageBox.Show("Nothing is selected ", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        UserCount();
    }

Your function returns null because no item is selected. So person is of course null. You should handle this in your FindPerson-Function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top