0

I'm creating a Windows Forms 2.0 app in Visual Studio 2008. The form has a DataGridView control which will have rows programmatically added to it with the overload Add(ByVal ParamArray Values()), as shown:

dgv.Rows.Add (var1, var2, var3, varEtc)

Is there a way to refer to the cells by name rather than by relying on their order..?

The dgv will have many columns, and referring to them by order will be confusing as I develop the app. It would be much easier to refer to them by some name or index string.

Unfortunately the DataGridView classes are many and vast, and I don't know which direction to go in. I have a half-baked idea to create each row object first, configure it, and and then add it to the collection, as shown below:

Dim dgvr as DataGridViewRow = New DataGridViewRow
...more code needed...
dgvr.SomeProp.ID    = var1
dgvr.SomeProp.NameF = var2
dgvr.SomeProp.NameL = var3
dgvr.SomeProp.Etc   = varEtc
dgv.Rows.Add (dgvr)

I'm sure this isn't the only way, and not yet even a functional one. Can I make this work..? What other ways are there..? Anything better..?

spinjector
  • 3,121
  • 3
  • 26
  • 56
  • 1
    When adding columns, assign `Name` property of the columns. Then refer the cells by column name, for example `dgvr.Cells["FirstName"].Value = "John";` Also in general consider using data binding to a `BindngList` or a `DataTable`. It make data manipulation and data display much easier. – Reza Aghaei Jun 20 '19 at 21:13
  • 1
    https://stackoverflow.com/questions/10063770/how-to-add-a-new-row-to-datagridview-programmatically?rq=1 May help – Magic Mick Jun 21 '19 at 01:37
  • Thanks. Mick's link pointed me on the trail to getting what I was hoping for. I'll add my own answer to the OP. – spinjector Jun 21 '19 at 18:23

1 Answers1

0

The link in the comment from Mick on my OP set me on the road to what I was hoping for - which turned out to be a few steps beyond what I originally conceived.

What I ended up with was a class extension of DataGridViewRow. It adds a the new extension function GetCellByColumnCaption, which does exactly that: it returns a DataGridViewCell object corresponding to the caption of the cell's column in the DataGridView control.

Doing it this way removes the control names from being an issue. Now I can simply refer to the cells in new rows by the most visible identifier they have: the column header text.

Here's a working example...

Public Class Form1

    Private Sub Form1_Load( _
                        ByVal sender As Object, _
                        ByVal e As System.EventArgs _
                        ) _
                        Handles Me.Load

        'Remove the new blank row.
        dgv.AllowUserToAddRows = False

    End Sub

    Private Sub Button1_Click( _
                        ByVal sender As System.Object, _
                        ByVal e As System.EventArgs _
                        ) _
                        Handles Button1.Click

        Dim newRowIdx As Integer = dgv.Rows.Add()
        Dim newRowObj As DataGridViewRow = dgv.Rows.Item(newRowIdx)
        newRowObj.GetCellByColumnCaption("ID").Value = "123"
        newRowObj.GetCellByColumnCaption("Name").Value = "Bob"
        newRowObj.GetCellByColumnCaption("Etc").Value = "Red"

    End Sub

End Class

Module ClassExtensions
    'Note: The Extension() attribute requires .Net 3.5 or above. 
    <System.Runtime.CompilerServices.Extension()> _
    Friend Function GetCellByColumnCaption( _
                        ByVal dgvr As DataGridViewRow, _
                        ByVal colCaption As String _
                        ) _
                        As DataGridViewCell

        For Each cell As DataGridViewCell In dgvr.Cells
            Dim hdrText = LCase(cell.OwningColumn.HeaderText)
            colCaption = LCase(colCaption)
            If hdrText = colCaption Then
                GetCellByColumnCaption = cell
                Exit Function
            End If
        Next
        GetCellByColumnCaption = Nothing
    End Function

End Module
spinjector
  • 3,121
  • 3
  • 26
  • 56