如何从 Header Text 属性获取 DGV 列的 Design > Name 属性

问题描述

我正在尝试检查 CheckedListBox1 中未选中的项目,并根据返回的值隐藏 DataGridView1 中的相关列,但问题是 CheckedListBox1 中显示的值是 DGV 列的 HeaderText 属性,而不是 Name 属性需要在 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 列的“名称属性

解决方法

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

试试这个:

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 是必需的!

[编辑]

此代码在 .ItemCheck 事件中执行。当表单启动时 我遍历所有可用的列,填充 CheckedBoxList1 并作为 默认情况下它们是未选中的,但我希望它们被选中 列在开始时可见

如果您想更改 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 循环 ;)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...