20

我在 a 中有一些项目CheckedListBox,我想禁用其中CheckBox的第一项。
即我想禁用 中的第一项CheckedListBox,因为我想直观地告诉用户该选项不可用。

4

11 回答 11

18

结合上述两个部分答案对我来说非常有用。将您的项目添加到列表中:

myCheckedListBox.Items.Add(myItem, myState);

对于应该禁用的项目,myState 是 CheckState.Indeterminate。然后添加一个事件处理程序以防止这些项目被更改:

myCheckedListBox.ItemCheck += (s, e) => { if (e.CurrentValue == CheckState.Indeterminate) e.NewValue = CheckState.Indeterminate; };

这不允许您将此列表中的“不确定”用于其正常目的,但它的外观确实与人们对禁用项目的期望非常相似,并且它提供了正确的行为!

于 2013-08-04T22:23:58.897 回答
18

虽然这篇文章已经很老了,但最后添加的答案已经在今年四月提交,
我希望这对某人有所帮助。
我追求类似的东西:一个类似于许多安装程序的选中列表框,它提供了一个选项列表,其中一些功能是必需的,因此被选中禁用。
感谢这篇文章(我可以使用带有 CheckedListBox 的 DrawItem 事件处理程序吗?)我设法做到了,将CheckedListBox控件子类化。
由于链接帖子中的 OP 状态,在CheckedListBox控件中该OnDrawItem事件永远不会被触发,因此子类化是必要的。
这是非常基本的,但它有效。这是它的样子(CheckBox上面是为了比较):

选中的列表框

注意:禁用的项目实际上是禁用的:单击它没有任何效果(据我所知)。

这是代码:

public class CheckedListBoxDisabledItems : CheckedListBox {
    private List<string> _checkedAndDisabledItems = new List<string>();
    private List<int> _checkedAndDisabledIndexes = new List<int>();

    public void CheckAndDisable(string item) {
        _checkedAndDisabledItems.Add(item);
        this.Refresh();
    }

    public void CheckAndDisable(int index) {
        _checkedAndDisabledIndexes.Add(index);
        this.Refresh();
    }

    protected override void OnDrawItem(DrawItemEventArgs e) {
        string s = Items[e.Index].ToString();

        if (_checkedAndDisabledItems.Contains(s) || _checkedAndDisabledIndexes.Contains(e.Index)) {
            System.Windows.Forms.VisualStyles.CheckBoxState state = System.Windows.Forms.VisualStyles.CheckBoxState.CheckedDisabled;
            Size glyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
            CheckBoxRenderer.DrawCheckBox(
                e.Graphics,
                new Point(e.Bounds.X + 1, e.Bounds.Y + 1), // add one pixel to align the check gliph properly
                new Rectangle(
                    new Point(e.Bounds.X + glyphSize.Width + 3, e.Bounds.Y), // add three pixels to align text properly
                    new Size(e.Bounds.Width - glyphSize.Width, e.Bounds.Height)),
                s,
                this.Font,
                TextFormatFlags.Left, // text is centered by default
                false,
                state); 
        }
        else {
            base.OnDrawItem(e);
        }
    }

    public void ClearDisabledItems() {
        _checkedAndDisabledIndexes.Clear();
        _checkedAndDisabledItems.Clear();
        this.Refresh();
    }
}

像这样使用它:

checkedListBox.Items.Add("Larry");
checkedListBox.Items.Add("Curly");
checkedListBox.Items.Add("Moe");

// these lines are equivalent
checkedListBox.CheckAndDisable("Larry");
checkedListBox.CheckAndDisable(0);

希望这可以帮助某人。

于 2015-07-12T17:19:17.077 回答
12

禁用项目不是一个好主意,用户不会有很好的反馈,点击复选框不会有任何效果。您不能使用自定义绘图使其明显。最好的办法是简单地省略该项目。

但是,您可以使用 ItemCheck 事件轻松击败用户:

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
        if (e.Index == 0) e.NewValue = e.CurrentValue;
    }
于 2010-12-06T17:01:41.673 回答
10

要禁用任何特定项目,请使用以下命令:

checkedListBox1.SetItemCheckState(0, CheckState.Indeterminate);

SetItemCheckState获取项目的索引,并且CheckStateEnum Indeterminate用于显示阴影外观

于 2012-11-27T11:05:02.643 回答
5

我知道已经有一段时间了,但我在搜索列表框时发现了这个,并认为我会将它添加到讨论中。

如果您有一个列表框并且想要禁用所有复选框以便无法单击它们,但不禁用控件以便用户仍然可以滚动等,您可以这样做:

listbox.SelectionMode = SelectionMode.None
于 2014-01-29T22:50:13.647 回答
3

CheckedListBox 不会以这种方式工作。CheckedListBox.Items是字符串的集合,因此它们不能被“禁用”。

以下是一些可能对您有所帮助的解决方案的讨论:这里这里

于 2010-12-06T16:54:17.820 回答
1

解决方案是使用事件ItemChecking

_myCheckedListBox.ItemChecking += (s, e) => e.Cancel = true;

这将取消对每个项目的所有检查,但您始终可以做更精细的解决方案,但测试当前.SelectedItem

于 2012-04-30T16:36:34.783 回答
1

这对我有用:

checkedListBox1.SelectionMode = SelectionMode.None;

这意味着无法选择任何项目

无:不能选择任何项目。

有关更多信息,您可以在此处查看:SelectionMode Enumeration

于 2017-10-13T08:03:48.963 回答
0

试试下面的代码:

Private Sub CheckedListBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles CheckedListBox1.MouseUp
        If (Condition) Then
         Me.CheckedListBox1.SelectedIndex = -1
        End If
End Sub
于 2015-04-05T06:54:14.603 回答
0

以下是我在我编写的帮助台应用程序中的做法:

首先,我做到了,所以当我在表单加载期间将它添加到列表中时,复选框是灰色的:

    private void frmMain_Load(object sender, EventArgs e)
    {
        List<string> grpList = new List<string>();
        ADSI objADSI = new ADSI();

        grpList = objADSI.fetchGroups();

        foreach (string group in grpList)
        {
            if (group == "SpecificGroupName")
            {
                chkLst.Items.Add(group, CheckState.Indeterminate);

            }
            else
            {
                chkLst.Items.Add(group);
            }

        }

然后我使用了一个事件,以便在单击时确保它保持单击状态:

    private void chkLst_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (chkLst.SelectedItem.ToString() == "SpecificGroupName")
        {
            chkLst.SetItemCheckState(chkLst.SelectedIndex, CheckState.Indeterminate);
        }
    }

这里的想法是在我的表单上设置它以便该框检查项目单击/选择。这样我可以用一块石头杀死两只鸟。在表单加载期间首次检查和添加项目时,我可以防止此事件引起问题。加上让它检查选择允许我使用这个事件而不是项目检查事件。最终的想法是防止它在加载期间搞砸。

您还会注意到,索引号是什么并不重要,该变量是未知的,因为在我的应用程序中,它从 AD 中获取特定 OU 中存在的组列表。

至于这是否是一个好主意,这取决于情况。我有另一个应用程序,其中要禁用的项目取决于另一个设置。在这个应用程序中,我只想让帮助台看到这个组是必需的,这样他们就不会从其中删除它们。

于 2014-10-03T21:20:03.577 回答
0

我认为另一种解决方案是使用Telerik组件。

ARadListControl可以为您提供该选项:

在此处输入图像描述

于 2015-04-05T08:31:56.493 回答