Link to home
Start Free TrialLog in
Avatar of BlakeMcKenna
BlakeMcKennaFlag for United States of America

asked on

Manually updating a bound DataGridView???

I have a DGV that is bound thru the Designer. On my form, the user has the chance to provide a parameter to retrieve a new set of data. My problem is, that I'm not sure how to tie the NEW dataset to the BindingSource or Dataset that the Designer created to reload my DGV!

Thanks,
Blake
Avatar of Ark
Ark
Flag of Russian Federation image

YourBindingSource.DataSource=NewDataSet
'YourBindingSource.DataMember = TableName_in_NewDataSet_If_Not_Same
Avatar of BlakeMcKenna

ASKER

For some reason that isn't working. Because the DGV needs to be populated dynamically based on some control values when the form loads, I removed the BindingSource as the DataSource in the Designer. I am manually binding the DGV to a new BindingSource (declared in my form as Dim BS As New BindingSource). Below is my code and how I build the DGV.

        Private Sub LoadGrid()
        Try
            If cmbYear.Text.Length > 0 And cmbMonth.Text.Length > 0 Then
                Dim ds As New DataSet
                ds = BL.GetNewTransactions(GetMonthLiteral(0, cmbMonth.Text), CInt(cmbYear.Text))
                dgvTrans.DataSource = Nothing
                bs.Clear
                bs.DataSource = ds
                bs.DataMember = "Transactions"

                If ds Is Nothing Then
                    Dim column As DataGridViewColumn

                    dgvTrans.Rows.Clear()
                    dgvTrans.Columns.Clear()

                    With dgvTrans
                        column = New DataGridViewColumn
                        column.Visible = False
                        dgvTrans.Columns.Add(column)

                        column = New DataGridViewColumn
                        Dim cmb As DataGridViewComboBoxCell = New DataGridViewComboBoxCell
                        cmb.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox
                        cmb.FlatStyle = FlatStyle.Popup
                        column.CellTemplate = cmb
                        column.HeaderText = "Account Name"
                        column.Width = 150
                        dgvTrans.Columns.Add(column)

                        column = New DataGridViewColumn
                        Dim dtp As CalendarCell = New CalendarCell
                        column.CellTemplate = dtp
                        column.HeaderText = "Date"
                        column.Width = 100
                        dgvTrans.Columns.Add(column)

                        column = New DataGridViewColumn
                        Dim cmb1 As DataGridViewComboBoxCell = New DataGridViewComboBoxCell
                        cmb1.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox
                        cmb1.FlatStyle = FlatStyle.Popup
                        column.CellTemplate = cmb1
                        column.HeaderText = "Merchant"
                        column.Width = 175
                        dgvTrans.Columns.Add(column)

                        column = New DataGridViewColumn
                        column.HeaderText = "Amount"
                        column.Width = 90
                        dgvTrans.Columns.Add(column)

                        column = New DataGridViewColumn
                        column.HeaderText = "Notes"
                        column.Width = 350
                        dgvTrans.Columns.Add(column)

                        column = New DataGridViewColumn
                        Dim btn As DataGridViewButtonCell = New DataGridViewButtonCell
                        column.CellTemplate = btn
                        column.HeaderText = "New Row"
                        column.Width = 100
                        dgvTrans.Columns.Add(column)
                    End With
                Else
                    Dim column As DataGridViewColumn

                    With dgvTrans
                        .Columns(0).Visible = False

                        Dim cmb1 As DataGridViewComboBoxCell = New DataGridViewComboBoxCell
                        cmb1.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox
                        cmb1.FlatStyle = FlatStyle.Popup
                        cmb1.DataSource = AccountsBindingSource
                        .Columns(1).CellTemplate = cmb1
                        .Columns(1).Width = 150
                        .Columns(1).HeaderText = "Account Name"

                        .Columns(2).Width = 100
                        .Columns(2).HeaderText = "Date"

                        Dim cmb2 As DataGridViewComboBoxCell = New DataGridViewComboBoxCell
                        cmb2.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox
                        cmb2.FlatStyle = FlatStyle.Popup
                        cmb2.DataSource = LKUPMerchantsBindingSource
                        .Columns(3).CellTemplate = cmb2

                        .Columns(4).Width = 90
                        .Columns(4).HeaderText = "Amount"

                        .Columns(5).Width = 350
                        .Columns(5).HeaderText = "Notes"

                        Dim cell As DataGridViewButtonCell = New DataGridViewButtonCell()
                        .Columns(6).CellTemplate = cell
                        .Columns(6).Width = 100
                        .Columns(6).HeaderText = "New Row"
                    End With
                End If
            End If

        Catch ex As Exception
            Dim strErr As String = "frmTransactions/LoadGrid() - " & ex.Message
            MessageBox.Show(strErr, "User Notification", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub
 Else
      Dim column As DataGridViewColumn
      With dgvTrans
            .DataSource = bs '<===ADDED

Open in new window

BTW, why you build unbound columns if 'BL.GetNewTransactions' returns nothing (does it really returns nothing or just emty table or what?). You can add table to ds, add columns to this table and bind this table to dgv. Then you don't need If..Else - just assign dgv columns to table. You can set
 dgv.AutoGenerateColumns = False
column = New DataGridViewColumn
Dim cmb As DataGridViewComboBoxCell = New DataGridViewComboBoxCell
cmb.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox
'......
column.DataPropertyName = "YourTableFieldName" '<== ADDED
dgvTrans.Columns.Add(column)

Open in new window

I guess the reason I'm doing it this way is because I want the columns to always show up on the dgv whether there is data or not. If there is another way to accomplish this...I would love to know.

Thanks,
As I mentioned above, there are 2 ways to display columns:
Bind datatable to datagridview and:
1. Set .AutogenerateColumns property to true and mantain columns template like you did in first part pf your If
2. Set .AutogenerateColumns property to false and create columns like in your second part (adding appropriate .DataPropertyName to each column)
In both cases, even if table is empty but contains columns - dgv will contain columns you need. Don't know what BL.GetNewTransactions() returns - datatable or dataset, anyway you can do:
If ds Is Nothing Then
   ds = New DataSet
   With ds.tables.Add("Transactions") 
      .Columns.Add("Account_Name", GetType(String))
      .Columns.Add("Account_Date", GetType(Date))
      .Columns.Add("MerchantID", GetType(Integer))
   End With
End If
bs.DataSource = ds
bs.DataMember = "Transactions"

Open in new window

Well, I have the code working to a point. The number of records that should be returned populate the grid with the correct number of rows, however, there is no Data in the columns. I just tried to assign the "DataPropertyName"  and that showed data for 3 of the 5 columns. However, the other 2 columns are comboboxes and their data isn't showing up. The comboboxes aren't even being loaded. Not sure why that's happening. Again, all the databinds are dynamic based off of a year and month parameter. This grid is basically a checkbook register. Also, for some reason the button text doesn't appear on the button. You can see how I have it coded in my logic above.
Can you show  BL.GetNewTransactions code?
I've renamed it to GetMonthlyTransactions().

        Public Function GetMonthlyTransactions(ByVal iMonth As Integer, ByVal iYear As Integer) As DataSet
        Dim ds As New DataSet

        Try
            ds = DL.GetMonthlyTransactions(iMonth, iYear)

            If Not ds Is Nothing Then
                Return ds
            Else
                Return Nothing
            End If

        Catch ex As Exception
            strErr = "clsBusinessLayer/GetAllocations() - " & ex.Message
            Throw
        End Try
    End Function
    '
    '
    '
        Public Function GetMonthlyTransactions(ByVal iMonth As Integer, ByVal iYear As Integer) As DataSet
        Try
            If DBConnection() Then
                ds = New DataSet

                sSQL = "SELECT ID, acctName, dateOfTran, amount, merchantID, note " & _
                         "FROM dbo.Transactions " & _
                        "WHERE MONTH(dateOfTran) = " & iMonth & " AND YEAR(dateOfTran) = " & iYear
                cmd = New SqlCommand(sSQL, cnn)
                adp = New SqlDataAdapter
                adp.SelectCommand = cmd
                adp.Fill(ds, "Transactions")

                If ds.Tables(0).Rows.Count > 0 Then
                    Return ds
                Else
                    Return Nothing
                End If
            End If

        Catch ex As Exception
            strErr = "clsDataLayer/GetMonthlyTransactions() - " & ex.Message
            Throw
        End Try
    End Function
ASKER CERTIFIED SOLUTION
Avatar of Ark
Ark
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial