0

I am attempting to store an exact copy of a DataGridViewRow into the same row's tag, everything works fine and the results are as it should be... except that when I try to retrieve the value using the column Name(at the last line of the code), it tells me that the column name doesn't exist. But if I use the index, everything works fine.

I have tried using the method CreateCells() or Clone() the structure of the original table but still does not work.

I could stick with using the index. But I would prefer to obtain the values by Column Name. is that possible?

    ''Create and populate a datagridview with one row 
    Dim DGV As New DataGridView
    DGV.Columns.Add("No1", "No1")
    DGV.Columns.Add("No2", "No2")
    DGV.Columns.Add("No3", "No3")
    Dim Objects As New List(Of Object)
    Objects.Add("1")
    Objects.Add("2")
    Objects.Add("3")
    DGV.Rows.Add(Objects.ToArray)

    '' Loop to store a copy of itself into the Row's Tag
    For Each selectedrows As DataGridViewRow In DGV.Rows
        Dim DataGridViewRow As New DataGridViewRow
        Dim CellArray As New List(Of Object)
        DataGridViewRow.CreateCells(DGV)                      ''I have tried DataGridViewRow = selectedrow.clone and it still doesnt work
        For Each Cell As DataGridViewCell In selectedrows.Cells
            CellArray.Add(Cell.Value)
        Next
        DataGridViewRow.SetValues(CellArray.ToArray)
        selectedrows.Tag = DataGridViewRow
    Next

    DGV.Rows(0).Cells(0).Value = "Change"
    MessageBox.Show(DGV.Rows(0).Cells(0).Value)               ''Works (Output: Change)
    MessageBox.Show(DGV.Rows(0).Tag.Cells(0).Value)           ''Works (Output: 1)

    MessageBox.Show(DGV.Rows(0).Cells("No1").Value)           ''Works (Output: Change) 
    MessageBox.Show(DGV.Rows(0).Tag.Cells("No1").Value)       ''Doesnt Work (Output: System.ArgumentException: 'Column named No1 cannot be found.

Parameter name: columnName')

Ryan Tan
  • 344
  • 2
  • 11
  • 1
    The `.Tag` property is an `Object`. Does it help if you cast it like this: `MessageBox.Show(DirectCast(DGV.Rows(0).Tag, DataGridViewRow).Cells("No1").Value)`? Also, you should use [`Option Strict On`](https://stackoverflow.com/a/29985039/1115360). – Andrew Morton Sep 13 '19 at 08:05
  • Hello, thank you for the reply, I have tried what you have suggested and the same error message appeared. – Ryan Tan Sep 13 '19 at 08:17
  • Ahhh.... you haven't named the columns when you copied the cells. – Andrew Morton Sep 13 '19 at 08:24
  • hmm, i have already named the columns in the DGV.Columns.add(ColumnName,ColumnHeaderText). i would assume that it would copy all templates when i used the method createcells into DataGridViewRow. how do i name the columns? – Ryan Tan Sep 13 '19 at 08:38
  • I can't find anything from a quick look at the documentation that suggests you can. You could create a Dictionary(Of String, Integer) to get the column index from the name. – Andrew Morton Sep 13 '19 at 08:47
  • I suppose I could use Dictionary, but I was hoping for something much more straight forward. Thanks, Andrew :) – Ryan Tan Sep 13 '19 at 08:55
  • What are you really trying to achieve with the copy of a row inside a row's .Tag? XY problem? – HardCode Sep 13 '19 at 18:57
  • DataTables bound to DataGridViews have all sorts of version stuff and markings of for version state. Might want to check if datatable has the info you need. – Mary Sep 14 '19 at 05:40
  • Your column name in DataGridViewRow was gone, because you put an array when you perform the DataGridViewRow.SetValues. – user11982798 Sep 16 '19 at 00:44

1 Answers1

0

How about if you Try to change your lines:

    Dim rwIdx = 0
    For Each selectedrows As DataGridViewRow In DGV.Rows
        Dim myDataGridViewRow As New DataGridViewRow
        myDataGridViewRow = DGV.Rows(rwIdx)
        rwIdx = rwIdx + 1
        selectedrows.Tag = myDataGridViewRow
    Next

The above only will refer to the same row, not clone the data, and below, I will copy the selectedrows to another datagridview:

    Dim DGV As New DataGridView
    DGV.Columns.Add("No1", "No1")
    DGV.Columns.Add("No2", "No2")
    DGV.Columns.Add("No3", "No3")
    Dim Objects As New List(Of Object)
    Objects.Add("1")
    Objects.Add("2")
    Objects.Add("3")
    DGV.Rows.Add(Objects.ToArray)


    '' Loop to store a copy of itself into the Row's Tag
    Dim DataGridViewRow As New DataGridViewRow
    Dim myRowIdx As Integer = 0
    For Each selectedrows As DataGridViewRow In DGV.Rows
        DataGridViewRow = New DataGridViewRow
        Dim dgv2 As New DataGridView
        For Each col As DataGridViewColumn In DGV.Columns
            dgv2.Columns.Add(DirectCast(col.Clone, DataGridViewColumn))
        Next
        For Each Cell As DataGridViewCell In selectedrows.Cells
            dgv2.Rows(0).Cells(Cell.ColumnIndex).Value = Cell.Value
        Next
        selectedrows.Tag = dgv2.Rows(0)
    Next
    MessageBox.Show(DGV.Rows(0).Cells(0).Value.ToString)                                       ''Works (Output: 1)
    MessageBox.Show(DirectCast(DGV.Rows(0).Tag, DataGridViewRow).Cells(0).Value.ToString)      ''Works (Output: 1)

    DGV.Rows(0).Cells(0).Value = "Change"
    MessageBox.Show(DGV.Rows(0).Cells(0).Value.ToString)                                       ''Works (Output: Change)
    MessageBox.Show(DirectCast(DGV.Rows(0).Tag, DataGridViewRow).Cells(0).Value.ToString)      ''Works (Output: 1)


    MessageBox.Show(DGV.Rows(0).Cells("No1").Value.ToString)                                   ''Works (Output: Change) 
    MessageBox.Show(DirectCast(DGV.Rows(0).Tag, DataGridViewRow).Cells("No1").Value.ToString)  ''Works (Output: 1)
user11982798
  • 1,878
  • 1
  • 6
  • 8