0

我正在使用 C#。我的问题是关于一个不想听的讨厌的列表框。

代码:

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

运行该事件后,如果 ListBox 的项目计数小于或等于 0 或 ListBox.Items 不包含用户名,它将将用户名添加到列表中。如果它包含用户名或计数更大,它将在 for 循环中更新用户状态。

但是,当尝试替换该值时,它只是复制它。我还尝试在 '_user.Replace(_user, e.UserName + " " + available);' 下面添加一个 'Remove(_user)',但它只是重复。

我可以通过在我的计时器内添加一个“ListBox.Items.Clear”来解决这个问题,该计时器以 5 秒的间隔更新 ListBox:

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

但是,ListBox 项目闪烁。我不想让它眨眼,所以我正在寻找替代品。我搜索了很多相关的问题,但没有一个是成功的。帮助将不胜感激。

4

3 回答 3

2

根据评论,第一个问题似乎是这个子句:

!listBoxContacts.Items.Contains(e.UserName)

如果现有项目始终是用户名 +(空格)+可用性,则该子句将始终返回 false,因此始终触发添加新条目。您应该将该子句更改为:

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

下一个问题是循环 - 看起来您最终会尝试更新列表中每个人的状态,而不仅仅是与事件相关的特定用户。

最后,您不会替换列表框中的现有值。

您可能需要执行以下操作:

string currentItem = listBoxContacts.Items[i];
if(currentItem.Contains(e.UserName))
{
    listBoxContacts.Items[i] = e.UserName + " " + available;
}
于 2013-01-13T02:05:00.387 回答
1

问题是在你使用String.Replace的方法返回一个字符串它不会改变原始字符串。

从上面的链接:

返回一个新字符串,其中当前字符串中出现的所有指定 Unicode 字符或字符串都替换为另一个指定的 Unicode 字符或字符串。

所以我会做类似的事情:

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

您将不得不在for语句中检查用户名,否则您将在列表中重复用户名

像这样的东西:

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

}
于 2013-01-13T02:01:40.523 回答
1

replace 方法不会更改 _user,因为字符串是不可变的,您应该使用

_user = _user.Replace(_user, e.UserName + " " + available);
于 2013-01-13T02:02:29.713 回答