带有只读/禁用项目的WinForms列表框

问题描述 投票:0回答:6

有没有办法使列表框中的某些项目只读/禁用,以便无法选择它们?或者有没有类似ListBox的控件可以提供这个功能?

winforms listbox
6个回答
4
投票

ListBox 不支持这一点。 您可以固定某些东西,也可以取消选择选定的项目。 这是一个阻止选择偶数项的愚蠢示例:

private void listBox1_SelectedIndexChanged(object sender, EventArgs e) {
  for (int ix = listBox1.SelectedIndices.Count - 1; ix >= 0; ix--) {
    if (listBox1.SelectedIndices[ix] % 2 != 0) 
      listBox1.SelectedIndices.Remove(listBox1.SelectedIndices[ix]);
  }
}

但是闪烁非常明显,并且扰乱了键盘导航。 您可以通过使用 CheckedListBox 获得更好的结果,您可以防止用户选中某个项目的框:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
  if (e.Index % 2 != 0) e.NewValue = CheckState.Unchecked;
}

但现在您无法覆盖绘图以使用户明显看出该项目不可选择。 这里没有很好的解决方案,只是不在框中显示不应选择的项目要简单得多。


1
投票

@Hans解决方案导致项目ID选择了很短的时间,然后选择消失。我不喜欢这样 - 这可能会让最终用户感到困惑。

我更喜欢隐藏应该禁用的项目的一些编辑选项按钮:

        if (lbSystemUsers.Items.Count > 0 && lbSystemUsers.SelectedIndices.Count > 0)
            if (((RemoteSystemUserListEntity)lbSystemUsers.SelectedItem).Value == appLogin)
            {
                bSystemUsersDelete.Visible = false;
                bSystemUsersEdit.Visible = false;                    
            }
            else
            {
                bSystemUsersDelete.Visible = true;
                bSystemUsersEdit.Visible = true;
            }

这是列出用户的列表,并且不允许编辑实际登录到编辑面板的用户。


1
投票

ListBox
没有
ReadOnly
(或类似)属性,但您可以创建自定义
ListBox
控件。 这是一个对我来说非常有效的解决方案:

https://ajeethtechnotes.blogspot.com/2009/02/readonly-listbox.html

public class ReadOnlyListBox : ListBox 
{ 
    private bool _readOnly = false; 
    public bool ReadOnly 
    { 
        get { return _readOnly; } 
        set { _readOnly = value; } 
    } 

    protected override void DefWndProc(ref Message m) 
    { 
        // If ReadOnly is set to true, then block any messages 
        // to the selection area from the mouse or keyboard. 
        // Let all other messages pass through to the 
        // Windows default implementation of DefWndProc.
        if (!_readOnly || ((m.Msg <= 0x0200 || m.Msg >= 0x020E) 
            && (m.Msg <= 0x0100 || m.Msg >= 0x0109) 
            && m.Msg != 0x2111 
            && m.Msg != 0x87)) 
        {
            base.DefWndProc(ref m); 
        } 
    } 
} 

1
投票

我知道这是旧线程,但我将来会为其他读者发布解决方法。

listBox.Enabled = false;
listBox.BackColor = Color.LightGray;

这会将列表框的背景颜色更改为浅灰色。因此,这不是内置的“本机方式”,但至少给用户一些反馈,表明他不应该/无法编辑该字段。


0
投票

为了获得只读行为,我有 MyCBLLocked,一个与 MyCBL 复选框列表控件关联的布尔值,并且在 CheckItem 事件上我这样做:

private void MyCBL_ItemCheck(object sender, ItemCheckEventArgs e)
{
    if (MyCBLLocked)
        e.NewValue = e.CurrentValue;
    }

所以代替

MyCBL.Enabled = false;

我用

MyCBLLocked = true;

用户可以滚动浏览许多选择,但不会因为更改而搞乱事情。


0
投票

要使整个列表框只读,您可以将 SelectionMode 属性设置为 None。它将创建只读类型的列表框。

listBox.SelectionMode = SelectionMode.None;
© www.soinside.com 2019 - 2024. All rights reserved.