CheckedListBox 事件 *after* CheckState 改变

CheckedListBox event *after* CheckState changed

我的 WinForms 项目中有一个 CheckedListBox 控件和一个按钮。它包含一个项目列表,最多可以选择 5 个。我正在使用 ItemCheck 事件,因此每次用户选中或取消选中列表中的项目时,都会调用一个函数,如果所选项目的总数超过 5,则取消选中最后一个值:

private void NumbersListItemChecked(object sender, ItemCheckEventArgs e)
{
    CheckedListBox checkedItems = (CheckedListBox)sender;
    if (checkedItems.CheckedItems.Count > 4)
    {
        e.NewValue = CheckState.Unchecked;
    }
    RefreshButtonState();
}

这样,勾选的项目数就不会超过5个。

当我的 CheckedListBox 中选中的项目数量不是 5 时按钮控件应该被禁用,当它是时启用。每当状态发生变化时,我都会尝试调用此函数:

private void RefreshButtonState()
{
    if (NumbersList.CheckedItems.Count == 5)
    {
         ModifyButton.Enabled = true;
    }
    else
    {
        ModifyButton.Enabled = false;
    }
}

但是,即使我选中了 5 个项目,该按钮仍处于禁用状态,直到我尝试选中第 6 个,反之亦然 - 如果我选中 5 个,然后取消选中一个,该按钮将变为启用状态。我知道发生这种情况是因为在 实际更改发生之前 调用了该函数。

是否有 CheckedListBox 的事件在状态发生变化后立即被调用,而不是在它即将发生变化时被调用?

使用 ItemCheck 事件并检查已检查项目的新状态。新状态在事件 arg 中为 e.NewValue 。您可以检查 if(e.NewValue== CheckState.Check) 中的状态并在您的逻辑中使用它。

您不需要其他事件,只需处理 ItemChecked 并使用 e.NewValue 获取 CheckState 已更改,而不是在引发 ItemChecked 事件时更改。

private void NumbersListItemChecked(object sender, ItemCheckEventArgs e)
{
    var s = sender as CheckedListBox;
    var count = s.CheckedIndices.Count + (e.NewValue == CheckState.Checked ? 1 : -1);

    if (count > 5)
        e.NewValue = CheckState.Unchecked;

    ModifyButton.Enabled = count >= 5;
}