hi

I have datagridview which i want to add on several forms. Number of columons and all ather functionality remains the same.
to avoid creating size, columns, column names each time, i am trying to create class control for datagridview which will give me by default number of columns and size once i add the datagrid to form.

i have tried this . But it shows ten columns instead of five .

attached picture

Public Class ClsDgvJournal
    Inherits DataGridView
    Public Sub New()
        Width = 500
        Height = 200
        Dim Col1 = New DataGridViewTextBoxColumn With {.HeaderText = "AAA", .Name = "A", .Width = 100}
        Dim Col2 = New DataGridViewTextBoxColumn With {.HeaderText = "BBB", .Name = "B", .Width = 200}
        Dim Col3 = New DataGridViewTextBoxColumn With {.HeaderText = "CCC", .Name = "C", .Width = 100}
        Dim Col4 = New DataGridViewTextBoxColumn With {.HeaderText = "DDD", .Name = "D", .Width = 100}
        Dim Col5 = New DataGridViewTextBoxColumn With {.HeaderText = "EEE", .Name = "E", .Width = 100}
        Me.Columns.AddRange({Col1, Col2, Col3, Col4, Col5})

    End Sub

End Class

I think I see why. Lines 6 to 10 "New" or create columns. Line 11 adds 5 more columns.

How are you adding the control to your form? When I drag and drop this control onto a form I get 5 columns.

yes when i drag and drop i get five columns . But when i run it shows ten rows.

commented: Exactly. You have 5, then you add 5 in code, that's 10. +15

After adding control to form if i go and comment below line in class and then run it shows five columns only.

Me.Columns.AddRange({Col1, Col2, Col3, Col4, Col5})

My visual studio is updating so I can't test this. One thing you can try, that should work, is to make the columns fields/properties of the class:

Public Class ClsDgvJournal
    Inherits DataGridView

    Dim Col1 = New DataGridViewTextBoxColumn With {.HeaderText = "AAA", .Name = "A", .Width = 100}
    Dim Col2 = New DataGridViewTextBoxColumn With {.HeaderText = "BBB", .Name = "B", .Width = 200}
    Dim Col3 = New DataGridViewTextBoxColumn With {.HeaderText = "CCC", .Name = "C", .Width = 100}
    Dim Col4 = New DataGridViewTextBoxColumn With {.HeaderText = "DDD", .Name = "D", .Width = 100}
    Dim Col5 = New DataGridViewTextBoxColumn With {.HeaderText = "EEE", .Name = "E", .Width = 100}

    Public Sub New()
        Width = 500
        Height = 200
        Me.Columns.AddRange({Col1, Col2, Col3, Col4, Col5})
    End Sub
End Class

it gives error by undelining below

{Col1, Col2, Col3, Col4, Col5}

Error BC30311 Value of type 'Object()' cannot be converted to 'DataGridViewColumn'.

I've always found the easy way is to create the control manually, then look at the Form1.Designer.vb code to see what the code looks like. Then you can adapt it to what you want. For example, using the auto generated code I got

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Dim dgv As New ClsDgvJournal
        dgv.Location = New Point(10, 10)
        Me.Controls.Add(dgv)

    End Sub
End Class

Public Class ClsDgvJournal
    Inherits DataGridView

    Public Sub New()

        Me.Size = New Size(500, 200)

        For Each ch In {"A", "B", "C", "D", "E"}
            Dim col As New System.Windows.Forms.DataGridViewTextBoxColumn()
            col.Name = ch
            col.HeaderText = ch & ch & ch
            col.Width = IIf(ch = "B", 200, 100)
            Me.Columns.Add(col)
        Next

    End Sub

End Class
commented: Datagrid is generated at run time, how to name and write codes for it +3

Ok, did some more digging. So apparently you don't need to add the columns separately, the designer does it automatically when you drop the control onto the form. Just have them as fields in the derived class. The reason for the error is that in vb.net to initialize a new object, I forgot to use the As keyword instead of =:

Dim Col1 As New DataGridViewTextBoxColumn With {.HeaderText = "AAA", .Name = "A", .Width = 100}
Dim Col2 As New DataGridViewTextBoxColumn With {.HeaderText = "BBB", .Name = "B", .Width = 200}
Dim Col3 As New DataGridViewTextBoxColumn With {.HeaderText = "CCC", .Name = "C", .Width = 100}
Dim Col4 As New DataGridViewTextBoxColumn With {.HeaderText = "DDD", .Name = "D", .Width = 100}
Dim Col5 As New DataGridViewTextBoxColumn With {.HeaderText = "EEE", .Name = "E", .Width = 100}
Public Sub New()
    Width = 500
    Height = 200
End Sub
commented: its not working +3

Show the code you're using that isn't working. Saying it doesn't work doesn't help to fix it.

Datagrid is generated at run time, how to name and write codes for it

Like any other variable/object. You save the reference to it with the appropriate scope and use AddHandler to attach code to events.

You must add a condition because the columns are being added twice: in design-time and in run time. (DesignMode property from Windows Forms components not 100% reliable, so use this other):

    Public Sub New()
        Width = 500
        Height = 200
        If System.ComponentModel.LicenseManager.UsageMode = System.ComponentModel.LicenseUsageMode.Designtime Then
            Dim Col1 = New DataGridViewTextBoxColumn With {.HeaderText = "AAA", .Name = "A", .Width = 100}
            Dim Col2 = New DataGridViewTextBoxColumn With {.HeaderText = "BBB", .Name = "B", .Width = 200}
            Dim Col3 = New DataGridViewTextBoxColumn With {.HeaderText = "CCC", .Name = "C", .Width = 100}
            Dim Col4 = New DataGridViewTextBoxColumn With {.HeaderText = "DDD", .Name = "D", .Width = 100}
            Dim Col5 = New DataGridViewTextBoxColumn With {.HeaderText = "EEE", .Name = "E", .Width = 100}
            Me.Columns.AddRange({Col1, Col2, Col3, Col4, Col5})
        End If

    End Sub

Hi PM312
Actually when you drag control, this creates the five columns provided. So your custom control is correct. I should instead understand how to proceed to add lines. For example, if you assign a datasource starting from a DataTable, it adds the columns declared in the DataTable and as a result you will find yourself with other columns added.

Unexpectedly for me, when datasource is assigned, dessing mode seems to be bypassed. Commenting the If condition columns and rows can added to the datatable, directly to the control in dessing time or dynamically at run-time.

Public Class ClsDgvJournal
    Inherits DataGridView
    Public dataTbl As New DataTable
    Public Sub New()
        Try
            Width = 555
            Height = 90
            'If System.ComponentModel.LicenseManager.UsageMode = System.ComponentModel.LicenseUsageMode.Designtime Then'
            Dim dc1 As New DataColumn("AAA", GetType(String))
            Dim dc2 As New DataColumn("BBB", GetType(Int32))
            Dim dc3 As New DataColumn("CCC", GetType(Int32))
            Dim dc4 As New DataColumn("DDD", GetType(Int32))
            Dim dc5 As New DataColumn("EEE", GetType(Int32))
            dataTbl.Columns.AddRange(New DataColumn() {dc1, dc2, dc3, dc4, dc5})
            Dim row As DataRow = dataTbl.NewRow
            row.ItemArray = New Object() {1, 2, 3, 4, 5}
            dataTbl.Rows.Add(row)
            Me.DataSource = dataTbl
            'End If'
        Catch ex As Exception

        End Try
    End Sub

End Class

Public Class Form1

    Dim nItem As Int32 = 6
    Private Sub btnAddRow_Click(sender As Object, e As EventArgs) Handles btnAddRow.Click
        Try
            With ClsDgvJournal1.dataTbl
                Dim row As DataRow = .NewRow
                row.ItemArray = New Object() {nItem, nItem + 1, nItem + 2, nItem + 3, nItem + 4}
                .Rows.Add(row)
            End With
            nItem += 5
        Catch ex As Exception

        End Try
    End Sub
End Class
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.