如何从 Header 文本 属性 获取 DGV 列的设计 > 名称 属性

How to get Design > Name property of DGV column from Header Text property

我正在尝试浏览 CheckedListBox1 中的 un-checked 个项目,并根据返回的值隐藏 DataGridView1 中的相关列,但问题是 CheckedListBox1 中显示的值是 HeaderText 属性 DGV 列,而不是在 DGV 中隐藏该列所需的名称 属性。

见下面的代码:

For Each checked_item As Object In CheckedListBox1.Items
            If Not CheckedListBox1.CheckedItems.Contains(checked_item) Then
                DataGridView1.Columns("").Visible = False
            End If
        Next

在引用列的 HeaderText 属性 时,有没有办法检索 DGV 列的“名称”属性?

试试这个:

For Each checked_item As Object In CheckedListBox1.Items
        Dim oCol As DataGridViewColumn = DataGridView1.Columns _
            .Cast(Of DataGridViewColumn)() _
            .Where(Function(x) x.HeaderText = checked_item).SingleOrDefault()
        If oCol IsNot Nothing Then oCol.Visible = _
            Not CheckedListBox1.CheckedItems.Contains(checked_item)
Next 

注意:System.Linq为必填项!

[编辑]

this code is executed in the .ItemCheck event. When the form starts up I loop through all available columns, populate CheckedBoxList1 and as default they are un-checked but I want them checked as I want the columns to be visible at start

如果您想更改 CheckListBox 中当前所选项目的列的可见性(在 ItemCheck 事件中),请使用:

Dim oCol As DataGridViewColumn = DataGridView1.Columns _
    .Cast(Of DataGridViewColumn)() _
    .Where(Function(x) x.HeaderText = checked_item).SingleOrDefault()
If oCol IsNot Nothing Then oCol.Visible = _
    Not CheckedListBox1.CheckedItems.Contains(CheckedListBox1.SelectedItem)

你看出区别了吗?

主要区别在于:没有 foreach 循环 ;)

您不需要列名来隐藏列。你需要专栏。名称只是获取列的一种方式。问题在于您填充 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)