DataGridView.DataSource stopped triggering DataSourceChanged event - vb.net

In my code I used to do the following in the RowEnter event of another DataGridView:
dgv.DataSource = SomeFunctionReturningDataTable(ID)
The function looks like this:
Function SomeFunctionReturningDataTable(ByVal ID As String) As DataTable
If ds.Tables.Contains("Detail") Then
ds.Tables("Detail").Clear()
End If
'SQL query with DataAdapter using ID
Return ds.Tables("Detail")
End Function
The second datagridview (dgv) shows more detailed information about the currently selected record in the other datagridview.
The function is correctly returning a datatable with correct data.
I then do some formating in the datagridview for the new data in the DataSourceChanged event:
Private Sub dgv_DataSourceChanged(sender As Object, e As EventArgs) Handles dgv.DataSourceChanged
FormatDGV(dgv)
End Sub
However, the DataSourceChanged event has stopped triggering since a specific version. In the previous version this works.
However, I've been using this for numerous releases and it's always worked up until now and the code for this is exactly the same in both versions.
In the working version I've verified that the DataSourceChanged event is definitely firing after this line is completed dgv.DataSource = SomeFunctionReturningDataTable(ID).
The same line, with the same function, running in the new version is not triggering the event.
What could possibly have happened to break this?

Related

VS Studio DataGridView error

I am attempting to handle a local DB for a program I am doing, but I ran into this error that I can't get my head around! Whenever I attempt to edit a row in the gridview I get this error..
Screenshots:
https://i.gyazo.com/cc48a33863fada3e70e445620e6e9b2e.mp4
https://gyazo.com/5b184ea8aead4407e1bd2f0dd081b38c
You row has multiple column. Free column is a not null column.
When you add row, initialise the value of checkbox column.
dataGridView1.Rows[2].Cells[3].Value = true;
You need to add one event handler to your data grid and handle the error. Example
add the below code in your form loading event
AddHandler DataGridView1.DataError, AddressOf DataErrorHandler
Replace DataGridView1 with your data grid name and then create the below function and handle your error.
Private Sub DataErrorHandler(ByVal sender As Object, ByVal e As DataGridViewDataErrorEventArgs)
'handle the error or do nothing.
End Sub

How to get the value of a record from a datagrid on a double click event

Basically I have been researching for hours on end and cannot find the answer.
Im using Visual Studio 2012, SQL server, using Visual basic.
I want to transfer the value of record from a datagridtable after it is double clicked so that it will link to a page with the value of the previous values.
I have tried selectedrow ect but still cant get it to work, I have also looked into global variables to see if I could transfer it that way but sadly no luck as I need to be able to get the value.
This is what I currently have, it just displays the first record from the table.
Private Sub FlightDataGridView_CellDoubleClick(sender As Object, e As
DataGridViewCellEventArgs) Handles FlightDataGridView.CellDoubleClick
Dim SelectedRowView As Data.DataRowView
Dim SelectedRow As CompleteDataSet.FlightRow
SelectedRowView = CType(FlightBindingSource.Current, System.Data.DataRowView)
SelectedRow = CType(SelectedRowView.Row, CompleteDataSet.FlightRow)
Dim BookForm As New ViewFlights
BookForm.LoadBookForm(SelectedRow.Flight_ID)
BookForm.Show()
End Sub
In the load event for the 'ViewFlights' form I have this:
FlightBookingTableAdapter.FillByFlightID(CompleteDataSet.FlightBooking, Flight_ID:=)
However what goes after 'Flight_ID:='
Thanks for any help

refreshing datagridview after populate existing datatable in vb.net

I am working on a windows form application using VB.net. I have populated a Datagridview1( dataset1.existingtable is the datatable). Now i wish to get distinct values from one column of its datatable and then populate another Datagridview2(dataset2.uniquerecords is the datatable).
PROBLEM: Not able to refresh data in Datagridview2 using design mode. However i am able to refresh data when dynamically creating a datatable at runtime.
The below sub is called after an event after my form has loaded completely.
The below code does NOT work
Private Sub loaddistinctrecords()
uniquerecords = existingtable.DefaultView.ToTable(True, "column_name")
Datagridview2.Refresh()
End Sub
The below code works
Private Sub loaddistinctrecords()
Dim newuniquerecords As New DataTable()
newuniquerecords = existingtable.DefaultView.ToTable(True, "column_name")
Datagridview2.DataSource = newuniquerecords.DefaultView
End Sub
well it looks like one cannot directly assign a datatable to another datatable and expect the datagridview to update automatically if the datatable was created from design mode.
What one can do is simply clear the existing records and then merge records from the source datatable.
Private Sub loaddistinctrecords()
uniquerecords.Clear()
uniquerecords.Merge(existingtable.DefaultView.ToTable(True, "table_name"))
End Sub

Faux Databinding a Recordset to a Datagridview

I am updating a very old vb6 program that includes recordsets bound to an old third party grid control. The recordset functionality is so ingrained into the program that it is not an option to replace them. So, I replaced the unfunctional grid with a datagridview and I fill it using a dataadapter and a dataset. The problem is that the recordset was originally bound to the grid and using a dgv breaks the binding.
So this is what I am trying to do. I have a function that passes in the old recordset and the new dgv, and fills it. I would like to create a dynamic handler to the dgv's selectionchanged event to update the rs with the current position on the dgv (rs.aboluteposition = dgv.row), thus updating the rs cursor to the current position in the dgv, making a sort of faux data binding.
Something like this....
AddHandler dgv.SelectionChanged, AddressOf RefreshRecordset
Public Sub RefreshRecordset()
myRS.AbsolutePosition = dgv.Row
End Sub
A couple things though. I have to track if the event handler was already created, and the associated recordset that goes with this specific datagridview. Also, since this is a global function to update many dgvs with many rs, it needs to have a way to track the recordset. I was thinking of somehow using the tag of dgv? Maybe create a dictionary of all the recordsets then look it up by the name of the dgv?
Below is my original method that worked pretty well. I eventually refined it and put it in a class for each recordset. I also updated it to accept true dbgrids. By wrapping it in a class, I was able to remove the dictionaries. In the New function, I pass in either grid and a recordset. From there, I set up event handlers to handle both the grid row change and also the recordset MoveComplete event. I had to use the MoveComplete because the RecordsetChangeComplete has a bug and doesn't always fire correctly. I just check in the MoveComplete if the record count had changed. If so, refresh the grid. Lastly, I added a removehandler for each of the events in the finalize function.
////// The Original Answer //////
For instance, like this... (I CAN'T believe this worked...)
Public dict as new Dictionary(Of String, ADODB.Recordset)
Public Sub FillGrid(ByRef dgv as DataGridView, ByRef rs as ADODB.RecordSet)
'.... Fill the grid with the tableadapter, blah blah.
If Not dict.ContainsValue(rs) Then
dict.add(dgv.Name, rs)
AddHandler dgv.SelectionChanged, AddressOf RefreshRecordset)
' To make the event fire correctly, I think
dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect
End if
End Sub
Public Sub RefreshRecordset(sender As Object, e As System.EventArgs)
Dim dgv as DataGridView = Ctype(sender, DataGridView)
If dict.ContainsKey(dgv.Name) then
Dim rs as ADODB.Recordset = dict(dgv.Name)
rs.AbsolutePosition = dgv.CurrentCell.RowIndex
End if
End Sub
Now I need to create a handler to the recordset to refresh the dgv everytime the recordset is updated.
And btw, I know there are probably other ways to do this and I would absolutely would love to hear them! Please feel free!
Thanks!

New added items on the datagridview cannot be seen at runtime

I have a program that inserts data in access database and the user can view the newly added items in a data grid view. After i add new items to the database it cannot be seen in the datagridview while the program is running. I have to stop the program and run it again just to see the changes i made.
Here is how i load the datagridview:
Public Class frmSupplies
Private Sub frmSupplies_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'SuppliesDataSet.product_info' table. You can move, or remove it, as needed.
Me.Product_infoTableAdapter.Fill(Me.SuppliesDataSet.product_info)
End Sub
How can i view the newly added items while the program is still running?
I created a module that will call the "refresh" function for the datagridview. I added a new module to my project and added this codes:
Imports System.Data.OleDb
Module Module1
Dim con As New OleDbConnection("Provider=Microsoft.Jet.Oledb.4.0;Data Source= database path")
Sub REFRESHDGV()
Dim sql As String
sql = "SELECT * FROM [product info]"
Dim adapter As New OleDbDataAdapter(sql, con)
Dim dt As New DataTable("product info")
adapter.Fill(dt)
Form1.dgv1.DataSource = dt
End Sub
End Module
Hope this helps others!
Try wrapping around beginedit ... end edit
gridview.BeginEdit();
----
gridview.EndEdit();
I am not familiar with access (I use oracle). Oracle database can notify you if something has changes in your database, so you can refresh the datagridview. In your case you can have a button (for refresh the datagridView) or a timer and refresh it every x time (you know the time):
'I imagine that you have a bindingSource
bindingSource1.DataSource = Product_infoTableAdapter.GetData()
bindingSource1.ResetBindings(false)
Maybe you want to take a look in DataGridView DataBinding
When you bind an Access table to a grid on a Windows form and then change the data outside that application, the form or the grid simply do not have a way of knowing that data was changed, unless 1) they receive some kind of notification from Access, or 2) the application keep querying the data source to see if changes were made.
Option 1 there is not applicable with MS Access.
Your only option is to put a timer on the form to regularly check for changes (on a fixed interval) and reload the table and refresh the grid if changes were found.