您不需要列名来隐藏列。你需要这个专栏。名称只是获取列的一种手段。问题在于您填充CheckedListBox 的方式。显示HeaderText 非常有意义,因为这是用户实际看到的。您应该做的是将列本身放入CheckedListBox 并仅显示HeaderText。这样,项目就是列,例如
Dim columns = DataGridView1.Columns.Cast(Of DataGridViewColumn)().ToArray()
With CheckedListBox1
.DataSource = columns
.DisplayMember = NameOf(DataGridViewColumn.HeaderText)
End With
你发布的代码就变成了这样:
For i = 0 To CheckedListBox1.Items.Count - 1
Dim column = DirectCast(CheckedListBox1.Items(i), DataGridViewColumn)
column.Visible = CheckedListBox1.GetItemChecked(i)
Next
请注意,您通常应该在绑定时最后设置DataSource,但这似乎不适用于CheckedListBox,它不正式支持数据绑定。因此,首先设置DataSource。
编辑:
在将评论添加到有关ItemCheck 事件和启动时检查项目的问题中后,我将添加此内容。这里的关键是在列表初始化之前不要实际对事件采取行动,即所有项目都已被初始检查。一种方法是这样的:
Private isLoaded As Boolean = False
Private Sub Form1_Load(...) Handles MyBase.Load
'Bind the data and check the items in the CheckedListBox here.
isLoaded = True
End Sub
Private Sub CheckedListBox1_ItemCheck(...) CheckedListBox1.ItemCheck
If isLoaded Then
'Act here.
End If
End Sub
另一种方法是通过在初始化发生时不处理事件来防止引发事件。这可以通过多种方式完成,但如果您想这样做,我会将其作为练习留给您。
由于ItemCheck 事件在项目状态更改之前引发,因此您需要区别对待当前项目与其他项目。我上面的循环会变成这样:
For i = 0 To CheckedListBox1.Items.Count - 1
Dim column = DirectCast(CheckedListBox1.Items(i), DataGridViewColumn)
'For the item that is being checked/unchecked, use its new state.
'For other items, use their current state.
column.Visible = If(i = e.Index,
e.NewValue = CheckState.Checked,
CheckedListBox1.GetItemChecked(i))
Next
也就是说,如果最初检查了所有项目并且所有列最初都是可见的,那么它只是您需要关心的当前项目,因此根本不需要循环:
Dim column = DirectCast(CheckedListBox1.Items(e.Index), DataGridViewColumn)
column.Visible = (e.NewValue = CheckState.Checked)