views:

274

answers:

2

This is something that has been bugging me for a while as it is easily fixed but not desirable.

I have a DataGridView that has 5 columns. The first is called ID.

In vb.net the following line gives an error "Object reference not set to an instance of an object":

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

Obviously using the name is much better than a hard coded value to reference the column but wondering if there is anything i can do to get this to work correctly?

The datagridview datasource is BindingSource control with the datasource being a dataset.

Thanks in advanced

EDIT: Based on the answer I have created the following function that does exactly as 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
+2  A: 

Perhaps the column is not called what you think it is?

Have you checked the Columns(0).Name property to verify?

It might have been called "tablename_ID" or something by the BindingSource

codeulike
you are right, the column name is called "DataGridViewTextBoxColumn17". Bit odd, why would the BindingSource change this?
Belliez
I will add the code to this answer
Belliez
+1  A: 

Two tips:

1- By default, the Winforms designer creates an object in your forms Class for every column that exists in a DataGridView. So if you have a column named MyIdColumn, for instance, you should be able to access the column in the form code like this:

Me.MyIdColumn.Visible = False

If you want to access an element of the DataGridView, you could do something like this:

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

Using this trick, if the column name changes, there's no problem because you reference the column directly instead of a string representing a column name that could change.

2- Your GetColName method could be better; I would transform it into an extension method:

<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

Usage:

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

A lot nicer IMO!

Meta-Knight
Thank you, this is an excellent answer and learnt something new. You are right, it is much nicer. I did make a change the function to Friend and placed it in a module. Excellent, thanks.
Belliez