多个事件处理程序触发,为什么

本文关键字:为什么 程序 事件处理 | 更新日期: 2023-09-27 18:35:21

我很难解决这个问题。我已经在 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 循环并填充名为 Items 的 listBox,但由于某种原因,它再次转到函数顶部并清空所有列表。请告诉我为什么它再次执行该函数?当我再次选择另一个类别时,它会执行事件处理程序 3 次,然后执行 4 次,依此类推。为什么这样做呢?

多个事件处理程序触发,为什么

每次

执行此操作时:

  client.GetItemsCompleted += 

您将订阅者添加到事件,因此第二次它将触发两次(第三次三次,依此类推)。

在完成的方法中取消订阅 ( -= ):

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