如何禁用选中列表框中的复选框?

发布于 2024-10-06 03:52:28 字数 141 浏览 5 评论 0原文

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

I have some items in a CheckedListBox, I want to disable the CheckBox of first item in it.
i.e. I want to disable the first item in the CheckedListBox, because I want to tell the user visually that option is not available.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

猥琐帝 2024-10-13 03:52:28

结合以上两个部分答案对我来说效果很好。
将您的项目添加到列表中:

myCheckedListBox.Items.Add(myItem, myState);

其中 myState 是 CheckState.Inminated 表示应禁用的项目。
然后添加一个事件处理程序以防止这些项目被更改:

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

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

Combining 2 of the above partial answers worked great for me.
Add your items to the list with:

myCheckedListBox.Items.Add(myItem, myState);

Where myState is CheckState.Indeterminate for items that should be disabled.
Then add an event handler to keep those items from being changed:

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

This does not allow you to use 'Indeterminate' in this list for its normal purpose but it does give a look very similar to what one would expect for a disabled item and it provides the correct behavior!

旧时模样 2024-10-13 03:52:28

虽然这篇文章已经很老了,但最后添加的答案已经在今年四月提交了,
我希望这会对某人有所帮助。
我正在寻找类似的东西:一个选中的列表框,其行为类似于
很多安装程序,提供了需要某些功能的选项列表
因此,都被选中并被禁用。
感谢这篇文章(Can I use a DrawItem event handler与 CheckedListBox?
我成功地做到了这一点,子类化 CheckedListBox 控件。
正如链接帖子中的OP所述,在 CheckedListBox 控件中,OnDrawItem 事件永远不会被触发,
所以子类化是必要的。
这是非常基本的,但它确实有效。
这就是它的样子(上面的 CheckBox 用于比较):

checked list box

< em>注意:被禁用的项目确实被禁用:点击它没有任何效果(据我所知)。

这是代码:

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

希望这可以帮助某人。

Though this post is pretty old, the last added answer has been submitted in April this year,
and I hope this will help someone.
I was after something similar : a checked list box that behaves like
a lot of installers, which offer a list of options where some features are required and
thus are both checked and disabled.
Thanks to this post (Can I use a DrawItem event handler with a CheckedListBox?)
I managed to do that, subclassing a CheckedListBox control.
As the OP in the linked post states, in the CheckedListBox control the OnDrawItem event is never fired,
so subclassing is necessary.
It's very basic, but it works.
This is what it looks like (the CheckBox above is for comparison) :

checked list box

NOTE: the disabled item is really disabled : clicking on it has no effects whatsoever (as far as I can tell).

And this is the code :

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

Use it like this:

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

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

Hope this can help someone.

追星践月 2024-10-13 03:52:28

禁用项目并不是一个好主意,用户不会得到良好的反馈,即单击复选框不会产生任何效果。您不能使用自定义绘图来使其显而易见。最好的办法就是简单地省略该项目。

然而,您可以使用 ItemCheck 事件轻松击败用户:

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
        if (e.Index == 0) e.NewValue = e.CurrentValue;
    }

Disabling items isn't a great idea, the user will have no good feedback that click the check box won't have any effect. You cannot use custom drawing to make it obvious. Best thing to do is to simply omit the item.

You can however easily defeat the user with the ItemCheck event:

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
        if (e.Index == 0) e.NewValue = e.CurrentValue;
    }
怼怹恏 2024-10-13 03:52:28

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

checkedListBox1.SetItemCheckState(0, CheckState.Indeterminate);

SetItemCheckState 获取项目索引和 CheckState 枚举
不确定用于显示阴影外观

To disable any particular item use following:

checkedListBox1.SetItemCheckState(0, CheckState.Indeterminate);

SetItemCheckState takes index of item and CheckState Enum
Indeterminate is used to show shaded appearance

甜点 2024-10-13 03:52:28

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

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

listbox.SelectionMode = SelectionMode.None

I know it has been a while, but I found this in my search for a list box and thought I would add it to the discussion.

If you have a listbox and want to disable all of the checkboxes so they cannot be clicked, but not disable the control so the user can still scroll etc. you can do this:

listbox.SelectionMode = SelectionMode.None
一抹微笑 2024-10-13 03:52:28

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

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

The CheckedListBox will not work in this way. CheckedListBox.Items is a collection of strings so they cannot be "disabled" as such.

Here are some discussions about possible solutions that might help you: here and here.

你的心境我的脸 2024-10-13 03:52:28

这对我有用:

checkedListBox1.SelectionMode = SelectionMode.None;

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

无:无法选择任何项目。

有关详细信息,您可以在此处查看:选择模式枚举

This works for me:

checkedListBox1.SelectionMode = SelectionMode.None;

Which means no items can be selected

None: No items can be selected.

For more info, you can check it here: SelectionMode Enumeration.

北方的韩爷 2024-10-13 03:52:28

解决方案是使用事件 ItemChecking

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

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

The solution is to use the event ItemChecking:

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

This will cancel all the checking on every item, but you can always do more refined solution but testing the current .SelectedItem

拥抱影子 2024-10-13 03:52:28

以下是我在我编写的帮助台应用程序中执行此操作的方法:

首先,我将其设置为灰色,因为我在表单加载期间将其添加到列表中:

    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 中存在的组列表。

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

Here's how I did it in a helpdesk application I wrote:

First, I made it so the check box was greyed out as I added it to the list during form load:

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

        }

Then I used an event so that when clicked it ensures it stays clicked:

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

The idea here is that on my form it's set so that the box checks on item click/select. This way I could kill two birds with one stone. I could keep this event from causing problems when the item is first checked and added during form load. Plus making it check on select allows me to use this event instead of the item checked event. Ultimately the idea is to keep it from messing up during the load.

You'll also notice that it doesn't matter what the index number is, that variable is unknown because in my app it's grabbing a list of groups from AD that exist in a specific OU.

As to whether this is a good idea or not, that's dependent on the situation. I have another app where the item to disable is dependent on another setting. In this app I just want the helpdesk to see that this group is required so they don't go removing them from it.

天荒地未老 2024-10-13 03:52:28

尝试下面的代码:

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

Try Below Code:

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
平定天下 2024-10-13 03:52:28

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

RadListControl 可以为您提供该选项:

在此处输入图像描述

I think an alternative solution, is using Telerik components.

A RadListControl can give you that option:

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文