Using one DataTable as the source in multiple UserControls in WinForms - vb.net

I have created a local DataTable in my DataSet. I then have two User Controls with Data Grids on them.
I am trying to add data to the Data Table from UserControl1 and then be able to view this data in the UserControl2.
The Current structure is - DataSet - DataTableClients
DataGrids on both user controls have DataSource property set to 'DataTableClientsBindingSource" from the DataSet.
Adding clients works fine as I can see DataGrid rows populating in the UserControl1:
Dim clientsDT As DataTable = DataSet.DataTableClients
Dim row As DataRow
Dim i As Integer
For i = 1 To iClientNo
row = clientsDT.NewRow()
row("ClientNo") = Controls("LblClient" & i.ToString()).Text
row("Title") = Controls("CboTitle" & i.ToString()).Text
row("FirstName") = Controls("TxtFName" & i.ToString()).Text
row("Surname") = Controls("TxtSurname" & i.ToString()).Text
row("ReportName") = Controls("TxtFName" & i.ToString()).Text.Substring(0, 1) & " " & Controls("TxtSurname" & i.ToString()).Text
clientsDT.Rows.Add(row)
Next
However, when I switch to my UserControl2, the DataGrid on that control is empty, even though the DataSource is set and pointing to the same DataTable.
Help would be appreciated.

Related

Displaying Data from DataGridView in TextBox Visual Basic

I am creating a program in Visual Basic where I have a DataGridView connected to an access database and I want to select the row and have the items in the row (firstname and surname) to be displayed in a textbox (txtname) when then button select is pressed. I so far have been able to get one column to display so it either displays first name or last name but it wont display both.
Dim currentCellData As String
Dim StaffName As String
For i As Integer = 0 To staffList.SelectedCells.Count - 1
Dim colindex = staffList.SelectedCells.Item(i).ColumnIndex
Dim rowindex = staffList.SelectedCells.Item(i).RowIndex
currentCellData = staffList.Item(colindex, rowindex).Value.ToString
StaffName = currentCellData
txtName.Text = StaffName
Next
You can use concatenation, and there is no need for the for loop.
This should work if I have understood correctly:
txtName.Text = staffList.Item(0, rowindex).Value.ToString & " " & staffList.Item(1, rowindex).Value.ToString

Capturing an event such as mouse click in Datagridview in VB

Update 5/21/17. Thank you for the suggestion of using a Table. That was helpful. I actually figured it out. I made myinputable a global variable by declaring the Dim statement at the top and making it a Datagridview type. Now I can turn it off in the other event that I needed to do it.
I am a novice. I have created a Datagridview in VB 2015 to capture a bunch of data from the use. When the user is finished with the data entry, I want to store the cell values in my variables. I do not know how to capture any event from my dynamically created datagridview "myinputable." My code is below. Please help.
Private Sub inputmodel()
Dim prompt As String
Dim k As Integer
'
' first get the problem title and the number of objectives and alternatives
'
prompt = "Enter problem title: "
title = InputBox(prompt)
prompt = "Enter number of criteria: "
nobj = InputBox(prompt)
prompt = "Enter number of alternatives: "
nalt = InputBox(prompt)
'
' now create the table
'
Dim Myinputable As New DataGridView
Dim combocol As New DataGridViewComboBoxColumn
combocol.Items.AddRange("Increasing", "Decreaing", "Threashold")
For k = 1 To 6
If k <> 2 Then
Dim nc As New DataGridViewTextBoxColumn
nc.Name = ""
Myinputable.Columns.Add(nc)
Else
Myinputable.Columns.AddRange(combocol)
End If
Next k
' now add the rows and place the spreadsheet on the form
Myinputable.Rows.Add(nobj - 1)
Myinputable.Location = New Point(25, 50)
Myinputable.AutoSize = True
Me.Controls.Add(Myinputable)
FlowLayoutPanel1.Visible = True
Myinputable.Columns(0).Name = "Name"
Myinputable.Columns(0).HeaderText = "Name"
Myinputable.Columns(1).Name = "Type"
Myinputable.Columns(1).HeaderText = "Type"
Myinputable.Columns(2).Name = "LThresh"
Myinputable.Columns(2).HeaderText = "Lower Threshold"
'Myinputable.Columns(2).ValueType = co
Myinputable.Columns(3).Name = "UThresh"
Myinputable.Columns(3).HeaderText = "Upper Threshold"
Myinputable.Columns(4).Name = "ABMin"
Myinputable.Columns(4).HeaderText = "Abs. Minimum"
Myinputable.Columns(5).Name = "ABMax"
Myinputable.Columns(5).HeaderText = "Abs. Maximum "
Myinputable.Rows(0).Cells(0).Value = "Help"
If Myinputable.Capture = True Then
MsgBox(" damn ")
End If
End Sub
As #Plutonix suggests, you should start by creating a DataTable. Add columns of the appropriate types to the DataTable and then bind it to the grid, i.e. assign it to the DataSource of your grid, e.g.
Dim table As New DataTable
With table.Columns
.Add("ID", GetType(Integer))
.Add("Name", GetType(String))
End With
DataGridView1.DataSource = table
That will automatically add the appropriate columns to the grid if it doesn't already have any, or you can add the columns in the designer and set their DataPropertyName to tell them which DataColumn to bind to. As the user makes changes in the grid, the data will be automatically pushed to the underlying DataTable.
When you're done, you can access the data via the DataTable and even save the lot to a database with a single call to the Update method of a data adapter if you wish.

Sorting DataTable Column Using DataGridView

I'm trying to sort a DataTable that contains some dates and values. I pass the DataTable information to a DataGridView and sort the data, then try to pass it back.
The below code runs successfully, but does not produce any difference:
Form1.DataGridView1.DataSource = ChartTable
Form1.DataGridView1.Sort(Form1.DataGridView1.Columns(0), System.ComponentModel.ListSortDirection.Ascending)
ChartTable = CType(Form1.DataGridView1.DataSource, DataTable).Copy()
ChartTable = ChartTable.DefaultView.ToTable
For i = 0 To ChartTable.Rows.Count - 1
Debug.Print("ChartTable = " & ChartTable.Rows(i)(0) & ", DataGrid = " & Form1.DataGridView1.Rows(i).Cells(0).Value)
Next
Here's the Output from the Debug.Print
ChartTable = 30/12/15, DataGrid = 27/10/15
ChartTable = 27/10/15, DataGrid = 19/11/15
ChartTable = 29/12/15, DataGrid = 22/12/15
ChartTable = 22/12/15, DataGrid = 29/12/15
ChartTable = 19/11/15, DataGrid = 30/12/15
The ChartTable (which is the DataTable) is still in it's original un-sorted state.
Am I missing something?
I think that it's because Datagridview sorts the data for himself, not doing changes to his datasource. When you copy the datasource, are copying the non-sorted datatable.
To do what you want, i think you may have to do a process to get row by row of the datagridview to the datatable.
But, in my opinion, it should be a lot better (and faster) if you sort the info before to fill the datatable.
You can use this code to sort your data table:
Dim filterExp As String = ""
Dim sortExp As String = dt.Columns.Item(0).ColumnName
Dim i As Integer
Dim dtrow() As DataRow
dtrow = dt.Select(filterExp, sortExp, DataViewRowState.CurrentRows)
For i = 0 To dtrow.Length - 1
DataGridView1.Rows.Add(dtrow(i)(dt.Columns.Item(0).ColumnName))
Next

Control name from Variable or Dataset. (Combobox)(.items.add)(.datasource)

I've checked for hours but I can't seem to find anything to help.
I want to loop through tables and columns from a dataset and use the column name in a combobox.items.add() line, however the eventual goal is to fill the combobox from the dataset itself possibly in a combobox.datasource line.
The first problem is that I can't get the code correct to setup the combobox control where it allows me to use .items.add("") and in extension .datasource
Error Message = "Object reference not set to an instance of an object"
dstcopt is the dataset from a oledbDataAdapter .fill(dstcopt,"table") line (which returns correct values)
tc_opt is a tab name on a tab control where the comboboxes are
For Each dstable In dstcopt.Tables
For Each dscolumn In dstable.Columns
Dim colName As String = dscolumn.ToString
MsgBox(colName) 'This retuns "aantigen"
Dim cb As ComboBox = Me.tc_opt.Controls("cb_" & colName)
cb.Items.Add(colName)
'cb_aantigen.DataSource = dstcopt.Tables(dstable.ToString)
'cb_aantigen.DisplayMember = "aantigen"
'cb_atarget.DataSource = dstcopt.Tables(dstable.ToString)
'cb_atarget.DisplayMember = "atarget"
Next
Next
The second problem comes when I do it manually (which works) using the exact combobox names cb_aantigen and cb_atarget as seen in the comments.
The problem is that once the form is loaded and the cb's are filled with the correct values, I can't change the value in any single cb individually, when I change one value it changes them all (there is 15 comboboxes in total) I know this is down to using a dataset, but I don't know away to 'unlink them from each other or the dataset'
Not sure if I need to split this into 2 questions, but help on either problem would be appreciated.
EDIT:
After looking at only this section of code for a day. This is what I have come up with to tackle both the problems at once.
The combobox control not working was down to using a tab tc_opt instead of a groupbox gp_anti
The issue with splitting the dataset up into individual comboboxes, I've worked around by taking the value of each cell in the database and adding it separately, probably a better way to do it though
For Each dstable As DataTable In dstcopt.Tables
For Each dscolumn As DataColumn In dstable.Columns
Dim colName As String = dscolumn.ToString
Dim cb(2) As ComboBox
cb(0) = CType(Me.gp_anti.Controls("cb_" & colName), ComboBox)
cb(1) = CType(Me.gp_rec.Controls("cb_" & colName), ComboBox)
cb(2) = CType(Me.gp_nat.Controls("cb_" & colName), ComboBox)
For icb = 0 To cb.Count - 1
If Not (IsNothing(cb(icb))) Then
For irow = 0 To dstable.Rows.Count - 1
If dstable.Rows(irow)(colName).ToString <> Nothing Then
Dim icbitemdupe As Boolean = False
If cb(icb).Items.Contains(dstable.Rows(irow)(colName).ToString) Then
icbitemdupe = True
End If
If icbitemdupe = False Then
cb(icb).Items.Add(dstable.Rows(irow)(colName).ToString)
End If
End If
Next
End If
Next
Next
Next

Append text to existing row in datatable

I'm trying to make a calendar in vb.net and I have come across this problem. I want to append some text into an existing datatable row. When I watch my debugger it says:"In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.".
Dim aantalRijen As Integer = 1
For x = 0 To 6
Dim dttopdrachten As New DataTable
dttopdrachten = opdrachtendao.getOpdrachtenByDate(Today.AddDays(x))
If dttopdrachten.Rows.Count > aantalRijen Then
aantalRijen = dttopdrachten.Rows.Count
End If
Next
For z = 0 To aantalRijen - 1
Dim r As DataRow
r = dttAgenda.NewRow()
dttAgenda.Rows.InsertAt(r, z)
Next
For i = 0 To 6
Dim aantalItems As Integer = 0
Dim dttopdrachten As New DataTable
dttopdrachten = opdrachtendao.getOpdrachtenByDate(Today.AddDays(i))
aantalItems = dttopdrachten.Rows.Count
For j = 0 To aantalItems - 1
Dim info As String = dttopdrachten.Rows(j).Item(0).ToString & vbCrLf & dttopdrachten.Rows(j).Item(2).ToString & vbCrLf & dttopdrachten.Rows(j).Item(3).ToString & vbCrLf & dttopdrachten.Rows(j).Item(4).ToString & vbCrLf & dttopdrachten.Rows(j).Item(5).ToString & vbCrLf & dttopdrachten.Rows(j).Item(6).ToString
dttAgenda.Rows(j).Item(i) = info
Next
Next
dgvAgenda.DataSource = dttAgenda
In the code above, I first count how many rows I have to make. Afterwards I add the amount of rows to the datatable (columns are added before). Until here it works, but then when I keep debugging I get the error. I tried googling but nothing could help me so far.
Seem problem has been solved without changing anything. So if someone want to make a calendar. Here's the solution ;)