Search code examples
vb.netwinformsdatagridviewbindingsource

Using a datagridview to add records


I am using VS2008/.net fw 3.5sp1 and back into the coding life - and a little rusty to say the least :) Any help on the below would be great please.

I need to gather a list of input from a user, that I will work with later (pass to a teradata DWH with some other values). The input list involves two parts, a BSB ID and an Account ID. After some research it looks like the best option would be to create a class for the accounts, a list of accounts and bind that to a datagridview - of which I have done - but it looks like I can't add/edit. I have added a new button/add button to alter the data grid and get an error that I cannot programmatically add.

When I use accountList.AllowNew() = TRUE -- Error -- constructor on type bankaccount not found - but - I thought the constructor is the "new" sub in the class?

When I try accountsBindingSource.IsFixedSize = False it advises the property is read only.

For this - I've cut all the other code out to just this section, which requires one form (frmAccountLoad), with a datagridview dgvAccounts and a button btnNewLine.

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Data.Common
Imports System.Diagnostics
Imports System.Drawing
Imports System.Data.SqlClient
Imports System.Windows.Forms
'--------------------------------------------------------------------
Public Class frmAccountLoad
    ' This BindingSource binds the list to the DataGridView control. 
    Private accountsBindingSource As New BindingSource()

    Private Sub frmAccountLoad_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


        'Create list to hold accounts
        Dim accountList As New BindingList(Of BankAccount)
        accountList.AllowNew() = True
        'accountList.AllowEdit = True


        accountsBindingSource.DataSource = accountList


        dgvAccounts.DataSource = accountsBindingSource

        'dgvAccounts.Columns(0).HeaderText = "BSB"
        'dgvAccounts.Columns(1).HeaderText = "Account"

    End Sub
    Private Sub btnNewLine_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNewLine.Click
        'accountsBindingSource.IsFixedSize = False

        accountsBindingSource.AddNew()
    End Sub

End Class
'--------------------------------------------------------------------
Public Class BankAccount
    '----------------------------------------------------------
    'a bank account has both a BSB and an account number
    Private m_BSB As String
    Private m_Account As String

    '----------------------------------------------------------
    'Public Property
    Public Property BSB() As String
        Get
            Return m_BSB
        End Get
        Set(ByVal value As String)
            m_BSB = value
        End Set
    End Property
    Public Property Account() As String
        Get
            Return m_Account
        End Get
        Set(ByVal value As String)
            m_Account = value
        End Set
    End Property
    '----------------------------------------------------------
    Public Sub New(ByVal new_Bsb As String, ByVal new_Account As String)
        m_BSB = new_Bsb
        m_Account = new_Account
    End Sub

End Class

Solution

  • To be able to call AddNew on your BindingList the BankAccount should have a parameter-less constructor.

    You need to have a public parameter-less constructor if you need some initialization, or just remove any constructor if you don't need initialization, then the default parameter-less constructor will be used.

    Public Class BankAccount
        Public Property BSB As String
        Public Property Account As String
    
        Public Sub New()
            'Do initialization here if you need
            'Or Remove the constructor if you don't need any initialization.
        End Sub
    End Class
    

    Also you don't need to set accountList.AllowNew = True. It's enough to use a BindingList(Of T) as DataSource.

    Private accountList As BindingList(Of BankAccount)
    Private Sub frmAccountLoad_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        accountList = New BindingList(Of BankAccount)
        dgvAccounts.DataSource = BS
    End Sub
    

    Then you can call accountList.AddNew() wherever you need.