Tommy
Tommy

Reputation: 65

ListBox - I need to remove an item, but it keeps duplicating them

I'm using C#. And my question is about a nasty ListBox that just doesn't want to listen.

Code:

        void client_UserAvailable(object sender, IMAvailEventArgs e)
    {
        this.BeginInvoke(new MethodInvoker(delegate
        {
            if (listBoxContacts.Items != null)
            {
                string available = "";
                if (e.IsAvailable)
                    available = "Online";
                else
                    available = "Offline";

                if (listBoxContacts.Items.Count <= 0 || !listBoxContacts.Items.Contains(e.UserName))
                    listBoxContacts.Items.Add(e.UserName + " " + available);
                else
                {
                    for (int i = 0; i < listBoxContacts.Items.Count; i++)
                    {
                        string _user = (string)listBoxContacts.Items[i];
                        _user.Replace(_user, e.UserName + " " + available);
                    }
                }
            }
        }));
    }

Once I run that event, it will add the user(s) name to the list if the ListBox's item count is less than or equal to 0 or if the ListBox.Items doesn't contain the username. If it contains the username or if the count is greater, it will then update the user(s) status in the for loop.

HOWEVER, when trying to replace the value, it just duplicates it. I also tried adding a 'Remove(_user)' below '_user.Replace(_user, e.UserName + " " + available);', but it just duplicates.

I can fix this issue by adding a 'ListBox.Items.Clear' inside of my timer that updates the ListBox at a 5 second interval:

        private void timer_Tick(object sender, EventArgs e)
    {
        if (isOnline)
        {
            if (listBoxContacts.Items != null)
            {
                foreach (string user in friends)
                {
                    listBoxContacts.Items.Clear();
                    client.IsAvailable(user);
                    if (infoWindow != null)
                    {
                        infoWindow.Close();
                        infoWindow = null;
                    }
                }
            }
        }
    }

BUT, the ListBox items blink. I don't want it to blink, so I'm trying to find alternatives. I searched throughout a lot of related questions, but none were successfully helpful. Help would be greatly appreciated.

Upvotes: 0

Views: 331

Answers (3)

Mark Hall
Mark Hall

Reputation: 54532

The problem is in your use of String.Replace the method returns a string it does not alter the original string.

From above link:

Returns a new string in which all occurrences of a specified Unicode character or String in the current string are replaced with another specified Unicode character or String.

So I would do something like:

listBoxContacts.Items[i] = _user.Replace(_user, e.UserName + " " + available);

You are going to have to check for the UserName in your for statement or else you will get the username repeating in your list

something like this:

for (int i = 0; i < listBoxContacts.Items.Count; i++)
{
    if (((string)listBoxContacts.Items[i]).Contains(e.UserName))
    {
        listBoxContacts.Items[i] =  e.UserName + " " + available;
        break;
    }

}

Upvotes: 1

Chamila Chulatunga
Chamila Chulatunga

Reputation: 4914

Based on comments it looks like the first problem is this clause:

!listBoxContacts.Items.Contains(e.UserName)

If the existing item is always username + (space) + availability, then that clause will always return false, and therefore always trigger the addition of a new entry. You should change that clause to something like:

(!listBoxContacts.Items.Contains(e.UserName + " Online" ) && !listBoxContacts.Items.Contains(e.UserName + " Offline"))

The next problem is the loop - looks like you end up trying to update the status for everyone in the list, not just the particular user that the event relates to.

And finally you're not replacing the existing value in the listbox.

You probably need to do something like:

string currentItem = listBoxContacts.Items[i];
if(currentItem.Contains(e.UserName))
{
    listBoxContacts.Items[i] = e.UserName + " " + available;
}

Upvotes: 2

uowzd01
uowzd01

Reputation: 1000

The replace method doesn't change _user as strings are immutable, instead you should use

_user = _user.Replace(_user, e.UserName + " " + available);

Upvotes: 1

Related Questions