删除CheckListBox CheckedItems

时间:2016-12-12 14:39:43

标签: c# winforms

我有一个定时器事件可以执行多项操作。我试图让它做的一件事是以编程方式删除计时器点击我正在执行的已完成操作后检查的CheckListBox项。

这是计时器的代码以及我试图做的事情。

private void timer1_Tick(object sender, EventArgs e)
{
    string s;
    if (DbFirmwareUpdateComplete.WaitOne(1))
    {
        DbFirmwareUpdateComplete.Reset();
        mnuLoadKeyFile.Enabled = true;
    }

    if (DbUpdateComplete.WaitOne(1))
    {
        DbUpdateComplete.Reset();
        mnuLoadKeyFile.Enabled = true;
        btnLoad.Enabled = true;
    }
    if (CacheComplete.WaitOne(1))
    {
        CacheComplete.Reset();
        btnLoad.Enabled = true;
    }
    if (UpdateRunning)
    {
        bool UpdateDone = true;
        int StillActive = 0;
        // loop through all active jobs to check if all have completed
        foreach (clsCnaPair cna in ActiveJobs)
        {
            if (cna.Job.JobComplete == false)
            {
                UpdateDone = false;
                StillActive++;
            }

            else
            {
                if (cna.Job.UpdateSuccess)
                {
                    // Update color of CLB.Items.Selected if success.
                    int count = CLB.Items.Count;
                    for (int index = count; index > 0; index--)
                    {
                        if(CLB.CheckedItems.Contains(CLB.Items[index-1]))
                        {
                            CLB.Items.RemoveAt(index - 1);
                        }
                    }
                }
                else
                {
                    // Update color of CLB.Items.Selected if failed.
                }
            }
        }
        if (UpdateDone)
        {
            UpdateRunning = false;
            log("All Update jobs have finished.");
        }
        if (ckTop.Checked == true)
        {
            ckTop.Checked = false;
        }
        else
        {
            ckTop.Checked = false;
        }

当我运行该程序并且它击中了这篇文章时;

        if (cna.Job.UpdateSuccess)
        {
            // Update color of CLB.Items.Selected if success.
            int count = CLB.Items.Count;
            for (int index = count; index > 0; index--)
            {
                if(CLB.CheckedItems.Contains(CLB.Items[index-1]))
                {
                    CLB.Items.RemoveAt(index - 1);
                }
            }
        }

我收到错误:

  

System.ArgumentOutOfRangeException:InvalidArgument ='-1'的值对'index'无效。   参数名称:index

在这段代码之后发生错误;

private void CLB_SelectedIndexChanged(object sender, EventArgs e)
{
    // One of the CNA IPs was selected. sender is the CheckedListBox.
    // Here we want to display its fingerprint in the text box, or if the push is running, the status.

    // get the CnaPair class represented by this IP:
    clsCnaPair CnaPair = (clsCnaPair)CLB.Items[CLB.SelectedIndex];

    // Display the corresponding fingerprint string in the editBox:
    if (CnaPair.Job != null) txtStatus.Text = CnaPair.Job.GetStatus();
    else txtStatus.Text = CnaPair.GetInfo();
}

或者更具体地说:

clsCnaPair CnaPar = (clsCnaPair)CLB.Items[CLB.SelectedIndex];

我错过了什么?搜索谷歌,显示我正在进行删除的方式与那里找到的示例一致。

谢谢,

2 个答案:

答案 0 :(得分:0)

经过一些实验,我注释掉了CLB_SelecteIndexChanged代码,它现在用原始代码完成。

这留下了一个问题。剩下的CLB_SelectedIndexChanged代码的工作原理是什么。我将再研究一下这个代码,看看我可以用你们提供的代码搞清楚。

感谢m.rogalski和mcNets。

答案 1 :(得分:0)

当循环条件取决于ChecklistBox的内容时,修改循环内ChecklistBox的内容是危险的。一旦调用RemoveAt(),CheckedItems列表和CLB.Items.Count已经改变,你就会遇到问题。在这种情况下,循环使用无效的索引(-1)触发SelectedIndexChanged()事件。

最好在do-while循环中执行此操作:

bool done;
do
{
    done = true;
    for (int index = CLB.Items.Count; index > 0; index--)
    {
        if(CLB.CheckedItems.Contains(CLB.Items[index-1]))
        {
            CLB.Items.RemoveAt(index - 1);
            done = false;
            break;
        }
    }

}while(!done);

这样,每次删除一个项目时,都会突破并重新开始循环。