2

この問題を解決するのに苦労しています。私は 3 時間に及んでいますが、なぜこれが行われているのかわかりませんでした。コードは次のとおりです。

private void Catagory_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        int selectedCategoryId = categoryIdList[categoryListBox.SelectedIndex];

        client.GetItemsAsync(selectedCategoryId);
        client.GetItemsCompleted += 
            new EventHandler<GetItemsCompletedEventArgs>(client_GetItemsCompleted);
    }

void client_GetItemsCompleted(object sender, GetItemsCompletedEventArgs e)
{
        itemIdList.Clear();
        itemNameList.Clear();
        itemNumberList.Clear();
        itemDisplayList.Clear(); //Clears the Display List Items

        if (e.Error == null)
        {
            itemIdList = e.ItemIDList;
            itemNumberList = e.itemNumber;
            itemNameList = e.Result;

            for (int i = 0; i < itemIdList.Count; i++)
            {
                itemDisplayList.Add(new ItemDisplay { itemNumber = itemNumberList[i], itemName = itemNameList[i] });
            }

            //Populating the listbox controll with the itemDisplaylist...
            Items.ItemsSource = itemDisplayList;
        }
        else
        {
            MessageBox.Show("Problem in getting the items list.");
        }
    }

初めてカテゴリを変更すると、完全に機能します。完全に、関数GetItemsAsync(selectedCategoryId)を呼び出して結果を取得し、イベント ハンドラーを呼び出し、イベント ハンドラーclient_GetItemsCompleted()の内部動作が想定どおりに機能し、リストに適切なデータを設定し、itemNumber と itemName を表示することを意味します。リストボックス。しかし、カテゴリを再度変更して別のアイテムを取得すると、正しく機能しません。リストをクリアして、想定どおりにリストにデータを入力し、for ループを実行して、呼び出された listBox にデータを入力します。Itemsしかし、何らかの理由で再び関数の先頭に移動し、すべてのリストを空にします。関数を再度実行する理由を教えてください。別のカテゴリをもう一度選択すると、イベント ハンドラが 3 回実行され、次に 4 回実行されます。なぜこれをやっているのですか?

4

1 に答える 1

13

これが実行されるたびに:

  client.GetItemsCompleted += 

サブスクライバーをイベントに追加すると、2 回目は 2 回発生します (3 回目は 3 回など)。

完成したメソッドでサブスクライブを解除 ( -= ) します。

void client_GetItemsCompleted(object sender, GetItemsCompletedEventArgs e)
{
    try {
       /* .... */
    }
    finally {
        client.GetItemsCompleted -= 
            new EventHandler<GetItemsCompletedEventArgs>(client_GetItemsCompleted);
    }
}

または、すべての呼び出しの前にクライアント オブジェクトを開始します。

var client = new ...();
client.GetItemsAsync(selectedCategoryId);
client.GetItemsCompleted += 
            new EventHandler<GetItemsCompletedEventArgs>(client_GetItemsCompleted);
于 2012-05-26T18:26:41.003 に答える