DataGridView.Column (ColumnName as String) gives the error "The reference to the object is not installed in the instance of the object"

This is something that bothered me for a while, as it is easily fixed, but not desirable.

I have a DataGridView with 5 columns. The first is called an identifier.

In vb.net, the following line gives the error "Object reference not installed on object instance":

dgvJobs.Columns("ID").Visible = False ' ERROR
dgvJobs.Columns(0).Visible = False ' OK

Obviously, using a name is much better than a hard-coded value for a column reference, but I wonder if there is anything I can do to make this work correctly?

This datagridview data source is a BindingSource control with a data source as a dataset.

EDIT: Based on the answer, I created the following function that works exactly the way I need:

Private Function GetColName(ByVal name As String, ByRef dgv As DataGridView) As Integer
    Dim retVal As Integer

    For Each col As DataGridViewColumn In dgv.Columns
        If col.HeaderText = name Then
            retVal = col.Index
            Exit For
        End If
    Next

    Return retVal

End Function

Useage:

dgvJobs.Columns(GetColName("ID", dgvJobs)).Visible = False
+3
3

:

1- Winforms . , DataGridView. , MyIdColumn, :

Me.MyIdColumn.Visible = False

DataGridView, - :

Dim value = dgv.Item(MyIdColumn.Index, rowIndex).Value

, , , , , , .

2- GetColName ; :

<System.Runtime.CompilerServices.Extension()> _
Private Function GetColByHeaderText(ByVal dgv As DataGridView, ByVal name As String) As DataGridViewColumn

    For Each col As DataGridViewColumn In dgv.Columns
        If col.HeaderText = name Then
            Return col
        End If
    Next

    Return Nothing

End Function

:

dgv.GetColByHeaderText("ID").Visible = False

!

+2

, , ?

Columns (0).Name ?

"tablename_ID" - BindingSource

+2

Public class Form2 Private list As List (Of Person) Private Sub Form2_Load (sender ByVal As System.Object, ByVal e As System.EventArgs) processes MyBase.Load CreateDGV () PopulatingDGV ()

End Sub

Private Sub CreateDGV()
    dataGridView1.AllowUserToAddRows = False
    dataGridView1.RowHeadersVisible = False

    dataGridView1.Columns.Add("col1", "Column 1")
    Dim column2 As DataGridViewComboBoxColumn = CreateComboBoxColumn1()
    Dim column3 As DataGridViewComboBoxColumn = CreateComboBoxColumn2()
    dataGridView1.Columns.Add(column2)
    dataGridView1.Columns.Add(column3)
    'adding an event:
    'DataGridView1.EditingControlShowing += New DataGridViewEditingControlShowingEventHandler(AddressOf dataGridView1_EditingControlShowing)
    'DataGridView1.DataError += New DataGridViewDataErrorEventHandler(AddressOf dataGridView1_DataError)
End Sub

Private Function CreateComboBoxColumn1() As DataGridViewComboBoxColumn
    Dim column As New DataGridViewComboBoxColumn()
    If True Then
        column.Name = "column2"
        column.HeaderText = "Column 2"
        column.DropDownWidth = 120
        column.Width = 120
        column.MaxDropDownItems = 3
        column.Items.AddRange(New String() {"First name", "Last name", "E-mail"})
        column.FlatStyle = FlatStyle.Flat
    End If
    Return column
End Function

Private Function CreateComboBoxColumn2() As DataGridViewComboBoxColumn
    Dim column As New DataGridViewComboBoxColumn()
    If True Then
        column.Name = "column3"
        column.HeaderText = "Column 3"
        column.DropDownWidth = 150
        column.Width = 150
        column.MaxDropDownItems = 3
        column.FlatStyle = FlatStyle.Flat
    End If
    Return column
End Function
Private Sub PopulatingDGV()
    '1.ST COLUMN: some test data to populate dgv
    Dim companies As String() = {"Indian Info", "Cybex", "Admin"}
    For i As Integer = 0 To companies.Length - 1
        dataGridView1.Rows.Add(companies(i))
    Next

    '2.ND COLUMN: creating a generic list (of your data from the file):
    'I will not populate it from the file, only invent some example data:
    Dim persons As Person() = New Person() {New Person("Monica", "Trotsky", "monica@test.com"), New Person("Budh", "sagar", "budh@cybex.in")}
    list = New List(Of Person)()
    For Each p As Person In persons
        list.Add(p)
    Next
End Sub


Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    Try
        If DataGridView1.CurrentCell.ColumnIndex = 1 Then
            Dim combo As ComboBox = TryCast(e.Control, ComboBox)
            If combo IsNot Nothing Then
                RemoveHandler combo.SelectedIndexChanged, New EventHandler(AddressOf comboBox_SelectedIndexChanged)
                AddHandler combo.SelectedIndexChanged, New EventHandler(AddressOf comboBox_SelectedIndexChanged)
            End If
        End If
    Catch ex As Exception
        MessageBox.Show("Error:" & vbLf & vbLf & ex.Message)
    End Try
End Sub
Private Sub comboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
    Try
        Dim cb As ComboBox = DirectCast(sender, ComboBox)
        Dim selection As String = cb.Text
        If selection <> [String].Empty Then
            For Each dgvColumn As DataGridViewColumn In dataGridView1.Columns
                If dgvColumn.Name = "column3" Then
                    Dim row As Integer = dataGridView1.CurrentCell.RowIndex
                    Dim cell As DataGridViewComboBoxCell = DirectCast(dataGridView1(2, row), DataGridViewComboBoxCell)
                    'cell.Items.Clear();
                    Select Case selection
                        Case "First name"
                            If True Then
                                cell.DataSource = list
                                cell.DisplayMember = "firstName"
                                cell.ValueMember = cell.DisplayMember
                                Exit Select
                            End If
                        Case "Last name"
                            If True Then
                                cell.DataSource = list
                                cell.DisplayMember = "lastName"
                                cell.ValueMember = cell.DisplayMember
                                Exit Select
                            End If
                        Case "E-mail"
                            If True Then
                                cell.DataSource = list
                                cell.DisplayMember = "eMail"
                                cell.ValueMember = cell.DisplayMember
                                Exit Select
                            End If
                    End Select
                End If
            Next
        End If
    Catch ex As Exception
        MessageBox.Show("Error:" & vbLf & vbLf & ex.Message)
    End Try
End Sub

Friend Class Person
    Public Property firstName() As String
        Get
            Return m_firstName
        End Get
        Set(ByVal value As String)
            m_firstName = Value
        End Set
    End Property
    Private m_firstName As String
    Public Property lastName() As String
        Get
            Return m_lastName
        End Get
        Set(ByVal value As String)
            m_lastName = Value
        End Set
    End Property
    Private m_lastName As String
    Public Property eMail() As String
        Get
            Return m_eMail
        End Get
        Set(ByVal value As String)
            m_eMail = Value
        End Set
    End Property
    Private m_eMail As String

    Public Sub New(ByVal _fn As String, ByVal _ln As String, ByVal _em As String)
        firstName = _fn
        lastName = _ln
        eMail = _em
    End Sub
End Class

Private Sub DataGridView1_DataError(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles DataGridView1.DataError
    If e.Exception IsNot Nothing AndAlso e.Context = DataGridViewDataErrorContexts.Commit Then
        MessageBox.Show("CustomerID value must be unique.")
    End If
End Sub

Final class

+1
source

Source: https://habr.com/ru/post/1727645/


All Articles