Reputation: 65
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
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
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
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