0

私はC#を使用しています。そして、私の質問は、聞きたくないだけの厄介な ListBox についてです。

コード:

        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)」を追加しようとしましたが、重複するだけです。

5 秒間隔で ListBox を更新するタイマー内に「ListBox.Items.Clear」を追加することで、この問題を解決できます。

        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

文字列は不変であるため、replaceメソッドは_userを変更しません。代わりに、

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

問題はString.Replace、元の文字列を変更しない文字列を返すメソッドの使用にあります。

上記のリンクから:

現在の文字列内の指定された Unicode 文字または文字列のすべての出現箇所が、別の指定された Unicode 文字または文字列に置き換えられた新しい文字列を返します。

だから私は次のようなことをします:

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

ステートメントで UserName を確認する必要があります。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 に答える