Link to home
Create AccountLog in
.NET Programming

.NET Programming

--

Questions

--

Followers

Top Experts

Avatar of jaydwest
jaydwest

VB.net 2.0 Windows Forms DataGridView Get Cell Value from Column Name and Row
I'm new to VB.net and for months I have been searching for a way to get the value of a datagridview cell using the ColumnName and the Row.  I have been told on this site and several others either that you cannot do it, you can only get the value of a cell by using the cell index, or you can do it simply by referring to the cell by Cells("ColumnName").   After testing these suggestions, neither worked.  

This morning a did read another response on this site that was the best presentation on this subject yet but the author did not think you could do it.  But I really wanted to be able to get the value of a cell using the column name and the row.  Using this article as my starting point, here's what I found

1) You cannot find the cell associated with a DataGridColumn from the DataGridColumn.
2)  You cannot refer to a cell by name.
3)  There is no ordinal relationship between columns and cells, e.g. if column 2 = cell 8 then column 3 may not point to cell 9.
4)  However, you can get the DataGridColumn from a Cell using the OwningColumn property.  

At first the Cell.OwningColumn property seems backward but after thinking about it, the OwningColumn is the Foreign Key to DataGridColumn and the DataGridColumn is the parent of the cell (There are many cells in a Column).

Using this, I was able to create the code to generate a SortedList with the ColumnName as the Sort Field, and the Cell Index as the second field.  After testing this works greate.  I have added the code snippet below.   Essentially this code allows you to write formulas based on column names instead of cell index numbers, for example. (This is a simplified snipet that does not include reference to sorted list)

     TotalCost = Cost1 + Cost2

I would really appreciate any feedback on the algorithm and the code.  I hope this helps others.

PS Can I get some points for answering this question





Public dgvCells as New SortedList(Of String, Long)
 
'-- Load Sorted List when you first enter the DataGrid (Not Datagrid must have rows)
If dgvCells.Count = 0 then
   Dim rowCurr as DataGridViewRow = datagridview1.currentrow
   Dim strColumnName as string
   Dim dgvColumn as New datagridviewcolumn
   Dim i as Int16 = 0
   For i = 0 to rowCurr.Cells.count	-1
      dgvColumn  = rowCurr.Cells(i).OwningColumn
      if dgvColumn.IsDataBound then
         strColumnName = dgvColumn.DataPropertyName
      Else
	strColumnName = dgvColumn.name
      End If
	dgvCells.Add(strColumnName, i)
   Next
End If
 
'-- Get the Cell Value by ColumnName
Dim rowCurrent as DataGridViewRow = datagridview1.CurrentRow
		
Dim intColumnIndex as integer  = Cint(dgvCells("CompanyName"))
Dim strCompanyName as string = Cstr(rowCurrent.Cells(intColumnIndex).Value)

Open in new window

Zero AI Policy

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of SanclerSancler

I don't know what you've been reading/trying but it looks to me as though you have been solving a problem which doesn't exist.

Open a new project and drag controls onto the default form so it looks like the screenshot below.  Leave all the names as the default but alter the dgv's AllowUserToOrderColumns setting to True (so you can experiment with swapping columns around if you wish).  Copy the code below into the form.  Run it.

Doesn't that do what you want?  If so, what is it you want that it doesn't do?

Roger
Public Class Form1
 
    Private dt As New DataTable
 
    Private Sub maketable()
        Dim dc0 As New DataColumn("ID", GetType(Integer))
        dc0.AutoIncrement = True
        dt.Columns.Add(dc0)
        Dim dc1 As New DataColumn("Name", GetType(String))
        dt.Columns.Add(dc1)
        Dim dc2 As New DataColumn("Item", GetType(String))
        dt.Columns.Add(dc2)
        Dim dc3 As New DataColumn("CompanyName", GetType(String))
        dt.Columns.Add(dc3)
        For i As Integer = 0 To 5
            Dim dr As DataRow = dt.NewRow
            dr(1) = "Name" & i.ToString
            dr(2) = "Item" & i.ToString
            dr(3) = "Company" & i.ToString
            dt.Rows.Add(dr)
        Next
        dt.AcceptChanges()
    End Sub
 
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        maketable() ' get some dummy data
        DataGridView1.DataSource = dt
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'get the value from the current row
        Dim dgvr As DataGridViewRow = DataGridView1.CurrentRow
        If Not dgvr Is Nothing Then
            Label1.Text = dgvr.Cells("CompanyName").Value
        End If
    End Sub
 
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        'get the value from the row specified in the textbox
        If Not IsNumeric(TextBox1.Text) Then Exit Sub
        Dim rowindex As Integer = CInt(TextBox1.Text)
        If rowindex > DataGridView1.RowCount Then Exit Sub
        Dim dgvr As DataGridViewRow = DataGridView1.Rows(rowindex)
        If Not dgvr Is Nothing Then
            Label2.Text = dgvr.Cells("CompanyName").Value
        End If
    End Sub
 
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        'get the values from all rows
        Dim labeltext As String = ""
        For Each dgvr As DataGridViewRow In DataGridView1.Rows
            labeltext &= dgvr.Cells("CompanyName").Value & vbCrLf
        Next
        Label3.Text = labeltext
    End Sub
End Class

Open in new window

CellValueByColumnName.jpg

Avatar of jaydwestjaydwest

ASKER

Thanks for your response.  I understand now what has been happening.  I have not been defining the underlying table for the DataGridView. I have been creating a DataSourceand setting it as the Data Source for the DataGridView.  After reviewing your reponse, I created a new Test project and used the default form form1.vb.  I created a datasource using a SQL Server DB and itsContact Table. I then used the Contact table as the DataSource for the DataGridView.  I added a button on the form and created the proc:

   strContactLF = me.DataGridView1.CurrentRow.Cells("ContactLF").value

It fired the exception

     Column named ContactLF cannot be found. Parameter name: columnName

After reviewing your code, I understand how it would work.  However as an old Access Developer I'm used to just dragging and dropping controls on forms  

Since you generate the table on the form Load and I  create the Sorted List on the same event, processing time should be roughly equivalent.  Your approach has the benefit that the datatable exists if there are no rows in the DatagridView.  My approach does not have that because it is dependent that at least one row in the datagridview exists.  However, and for me it's a big however, I can move columns in the Datagrid using the designer and  using the Sorted List without modifying the code,  the DataGridView Cell Names are automatically reset when the Form is Loaded.  The code does not need to be updated and a new revision does not have to be documented.  I seem to find clients that want columns moved all the time and automatically reseetting cell names makes more sense to me.

Thanks again.

I spent more time reviewing your response and was wondering if the problem is that I'm using SQL Server as the datasource provider.  Does SQL Server provide the Column Names so that they can be  used as Cell Index.  

I have modified my test so that the code mimicks your code exactly.  The only difference seems to be that I'm using SQL Server and you used a local table that you created.

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


ASKER CERTIFIED SOLUTION
Avatar of SanclerSancler

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
Create Account

Thanks
.NET Programming

.NET Programming

--

Questions

--

Followers

Top Experts

The .NET Framework is not specific to any one programming language; rather, it includes a library of functions that allows developers to rapidly build applications. Several supported languages include C#, VB.NET, C++ or ASP.NET.