有没有办法使列表框中的某些项目只读/禁用,以便无法选择它们?或者有没有类似ListBox的控件可以提供这个功能?
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;
}
但现在您无法覆盖绘图以使用户明显看出该项目不可选择。 这里没有很好的解决方案,只是不在框中显示不应选择的项目要简单得多。
@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;
}
这是列出用户的列表,并且不允许编辑实际登录到编辑面板的用户。
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);
}
}
}
我知道这是旧线程,但我将来会为其他读者发布解决方法。
listBox.Enabled = false;
listBox.BackColor = Color.LightGray;
这会将列表框的背景颜色更改为浅灰色。因此,这不是内置的“本机方式”,但至少给用户一些反馈,表明他不应该/无法编辑该字段。
为了获得只读行为,我有 MyCBLLocked,一个与 MyCBL 复选框列表控件关联的布尔值,并且在 CheckItem 事件上我这样做:
private void MyCBL_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (MyCBLLocked)
e.NewValue = e.CurrentValue;
}
所以代替
MyCBL.Enabled = false;
我用
MyCBLLocked = true;
用户可以滚动浏览许多选择,但不会因为更改而搞乱事情。
要使整个列表框只读,您可以将 SelectionMode 属性设置为 None。它将创建只读类型的列表框。
listBox.SelectionMode = SelectionMode.None;