VB.NET listbox won't display list items - vb.net

lstSafaris.DataSource = Nothing
lstSafaris.Items.Clear()
lstSafaris.Refresh()
lstSafaris.Items.Add("No unclosed safaris")
lstSafaris.DrawMode = DrawMode.Normal
Try
Helpers.openConnection(sqlConn)
Dim sqlCmd As New SqlCommand("closingTables", sqlConn)
sqlCmd.CommandType = CommandType.StoredProcedure
Dim sqlDA As New SqlDataAdapter(sqlCmd)
sqlDA.Fill(sqlDS)
For counter As Integer = 0 To sqlDS.Tables(1).Rows.Count - 1
listSource.Add(sqlDS.Tables(1).Rows(counter).Item("allocation_id"), sqlDS.Tables(1).Rows(counter).Item("file_number"))
Next
If listSource.Count > 0 Then
lstSafaris.DataSource = New BindingSource(listSource, Nothing)
lstSafaris.ValueMember = "Key"
lstSafaris.DisplayMember = "Value"
End If
lstSafaris.Refresh()
sqlConn.Close()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "Error")
End Try
So guys that is my code for the Listbox, this is a Sub that is called when the program is launched and whenever the whole form is refreshed, so when the problem first runs it works fine but the problem is when the form is refreshed, it displays count is greater than one but its blank, it's like all the items are there but they are not displayed, what am I missing?

If listSource.Count > 0 Then
lstSafaris.DataSource = New BindingSource(listSource, Nothing)
lstSafaris.ValueMember = "Key"
lstSafaris.DisplayMember = "Value"
lstSafaris.DataBind()
End If
you need to bind the data and not need to refresh data or clear the Items just remove data source before assign any data to data source as shown below.
lstSafaris.DataSource = Nothing

If blank spots are showing up then it would seem like the binding is there, but the data isn't. I would do a quick-watch on your listsource dictionary after populating it and make sure that it is filled with data. If it has data then your
lstSafaris.ValueMember = "Key"
lstSafaris.DisplayMember = "Value"
lstSafaris.DataSource = New BindingSource(listSource, Nothing)
should work

Related

Adding all elements of an list in a dynamic table vb.net

Protected Sub createTable()
Try
Dim listB As New ArrayList()
Dim dt As New DataTable
Dim info As SessioneUtente = Session(SessionVariables.InformazioniUtente)
Dim id As String = info.getIdDisciplinaDefault.ToString
dt = operations.G_Number(id)
If dt.Rows.Count = 0 Then
notifica.Text = "There is no number for this id"
Else
For Each row In dt.Rows
list.Add(row(0))
listB.Add(row(0))
Next
listB.Add(23)
listB.Add(24)
listB.Add(25)
Dim cell1 As New TableCell
Dim cell2 As New TableCell
Dim Nr As New Label
Dim Icon As New Label
Dim row1 As New TableRow
Dim row2 As New TableRow
For Each item In listB
If list.Contains(item) Then
Nr.Text = item
Icon.Text = "<img = src='../Images/Icon1.png' />"
cell1.Controls.Add(Nr)
cell2.Controls.Add(Icon)
row1.Cells.Add(cell1)
row2.Cells.Add(cell2)
Else
Nr.Text = item & vbLf
Icon.Text = "<img = src='../Images/Icon2.png' />"
cell1.Controls.Add(Nr)
cell2.Controls.Add(Icon)
row1.Cells.Add(cell1)
row2.Cells.Add(cell2)
End If
Next
tabel.Rows.Add(row1)
tabel.Rows.Add(row2)
notifica.Visible = False
End If
Catch ex As Exception
Dim log As New Log
log.writeLog("default", ex)
End Try
End Sub
I'm dynamically populating a table via VB.NET using an arraylist but the table gets only the last element of the list. The list takes some elements from database and the other I add by myself. I need some help about displaying all the element of the list in the dynamic table.
Thank you in advance!
I would try moving my variables that I was dimensioning inside of my foreach loop. It appears to me that you are overwriting them each time. You seem to be overwriting the same memory location on each loop. Moving them inside of the loop should create a new memory location for each item in the list. I am guessing that you are seeing the correct number of rows but they all have the same values which happen to be the last item in the list. This is because it is being overwritten and there are only pointers to that memory location being added on each loop. You also need to move where you are adding it into the table inside of the loop for each iteration because right now you are only adding the last thing you set the row to and when you move those variables into the loop it is going to throw you an error. You want to add each row into the table while it is in scope with the current data.

Data grid view with combo box , add rows from data table

Search and display data in data grid view
Dim cmd As New OracleCommand("Select JV_CODE,JV_ACC_NAME,DEBIT,CREDIT From VOUCHER_DETAIL where VOUCHERNO =:Vno", sgcnn)
cmd.Parameters.Add("#Vno", OracleDbType.NVarchar2).Value = txtJVNo.Text.ToString.Trim
Dim daVD As New OracleDataAdapter(cmd)
Dim dtVD As New DataTable()
daVD.Fill(dtVD)
dgvAccDetail.AutoGenerateColumns = False
dgvAccDetail.DataSource = dtVD
dgvAccDetail.Rows(0).Cells(0).Value = dtVD.Rows(0).Item("JV_CODE").ToString.Trim
dgvAccDetail.Rows(0).Cells(1).Value = dtVD.Rows(0).Item("JV_ACC_NAME").ToString.Trim
dgvAccDetail.Rows(0).Cells(2).Value = dtVD.Rows(0).Item("DEBIT").ToString.Trim
dgvAccDetail.Rows(0).Cells(3).Value = dtVD.Rows(0).Item("CREDIT").ToString.Trim
Catch ex As Exception
MsgBox(ex.Message)
End Try
There are two rows in dtVD data table but result shows only one I stack with this some can tell what I'm doing wrong ?
The reason for this is that you are only assigning the one row. You have a couple options:
First, this code below here shouldn't really be necessary, of you setup the property binding on the grid. You'll get better performance that way if you use a bind. You don't have your GUI code here, but essentially your DataPropertyName field on the columns should be set.
dgvAccDetail.Rows(0).Cells(0).Value = dtVD.Rows(0).Item("JV_CODE").ToString.Trim
dgvAccDetail.Rows(0).Cells(1).Value = dtVD.Rows(0).Item("JV_ACC_NAME").ToString.Trim
dgvAccDetail.Rows(0).Cells(2).Value = dtVD.Rows(0).Item("DEBIT").ToString.Trim
dgvAccDetail.Rows(0).Cells(3).Value = dtVD.Rows(0).Item("CREDIT").ToString.Trim
If you insist on manually assigning the cell values, you cannot just do row 0 (that's the first row). You need to do all the rows in a loop.
For i as Integer = 0 to dtVD.Rows.Count - 1
dgvAccDetail.Rows(i).Cells(0).Value = dtVD.Rows(i).Item("JV_CODE").ToString.Trim
dgvAccDetail.Rows(i).Cells(1).Value = dtVD.Rows(i).Item("JV_ACC_NAME").ToString.Trim
dgvAccDetail.Rows(i).Cells(2).Value = dtVD.Rows(i).Item("DEBIT").ToString.Trim
dgvAccDetail.Rows(i).Cells(3).Value = dtVD.Rows(i).Item("CREDIT").ToString.Trim
Next

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.

Datagridview SelectedRows index error | Access and VB.NET

I have an error in my software. My form contains a DataGridView connected with MS_access database.
When I click on a row in the DataGridView, I get this error:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
My code:
Try
If (DataGridView1.Rows.Count <= 0) Then Return
FlatTextBox1.Text = String.Empty
FlatTextBox2.Text = String.Empty
FlatTextBox3.Text = String.Empty
RichTextBox1.Text = String.Empty
Dim indx As String = DataGridView1(1, DataGridView1.SelectedRows(0).Index).Value.ToString
Dim dt As DataTable = New DBConnect().selectdata(String.Format("SELECT famille3.Article, famille3.quantité, famille3.prixch, famille3.prixvn, famille3.dateex, famille3.description FROM famille3 where famille3.ID = {0} ", indx))
If dt.Rows.Count > 0 Then
FlatTextBox1.Text = dt.Rows(0)(0).ToString
FlatTextBox2.Text = dt.Rows(0)(1).ToString
FlatTextBox3.Text = dt.Rows(0)(2).ToString
FlatTextBox9.Text = dt.Rows(0)(3).ToString
FlatTextBox10.Text = (dt.Rows(0)(3).ToString - dt.Rows(0)(2).ToString) * dt.Rows(0)(1).ToString
FlatTextBox11.Text = dt.Rows(0)(4).ToString
RichTextBox1.Text = dt.Rows(0)(5).ToString
End If
dt.Dispose()
dt = Nothing
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
I think the stack is here
Dim indx As String = DataGridView1(1, DataGridView1.SelectedRows(0).Index).Value.ToString
How can I resolve it?
In a CellClick event of a DataGridView you receive a parameter of type DataGridViewCellEventArgs. This parameter contains the ColumnIndex and the RowIndex of the clicked cell. So getting the value of the column 1 of the clicked row is really simple as
Sub DataGridView1_CellClick(sender as Object,e As DataGridViewCellEventArgs)
Dim indx As Integer = Convert.ToInt32(DataGridView1(1, e.RowIndex).Value)
.....
Notice that I have applied a Convert.ToInt32 to the value of the first column. I assume that this is the numeric primary key to find your record. Remember that VB.NET allows you to freely convert string to numbers (VB6 compatibility) but in general this is considered a bad practice. Check your project properties and set Option Strict On instead and you will be forced to improve your code.
Another advice that I feel to give is to not write query in that way. This method is called sql string concatenation and it is the root of Sql Injection. (In your current case there is no big risk, but better to take good habits and always use parameterized queries)

Listview help needed

I am confused being a relatively new user to vb.net. Why my listview is not amending the value in the list? If I may, so I have a correct working of how listview displays its data from database. I have a general question in addition to my code problem.
I have five columns in my listview (0-4). Am I correct in saying that if my access database contained say 10 fields but I only needed to display five of them but one of them was field (9), then would code the list like my code below, which is not changing the value and will only display the list if I remove the 'else' statement.
What is the error? Many thanks
UPDATED CODE:
oledbCnn.ConnectionString = My.Settings.storageConnectionString
oledbCnn.Open()
'drcount = Convert.ToInt32(dr("RowCount"))
sql = "Select TOP 100 * from Requests ORDER BY [Date-time received] DESC"
Debug.Print(sql)
Dim oledbCmd As OleDbCommand = New OleDbCommand(sql, oledbCnn)
Using dr = oledbCmd.ExecuteReader()
'clear items in the list before populating with new values
'lvRequests.Items.Clear()
While dr.Read()
If dr.HasRows Then
Dim LVI As New ListViewItem
With LVI
.Text = dr(0).ToString()
.UseItemStyleForSubItems = False
.SubItems.Add(CDate(dr(5)).ToShortDateString())
.SubItems.Add(dr(1).ToString())
.SubItems.Add(dr(3).ToString())
If dr(3).ToString = "D" Then
.SubItems(3).Text = "Destroyed"
ElseIf dr(3).ToString = "O" Then
.SubItems(3).Text = "Out"
ElseIf dr(3).ToString = "I" Then
.SubItems(3).Text = "Intake"
End If
.SubItems.Add(dr(9).ToString())
If dr(9).ToString = "DEMO" Then
.SubItems(9).Text = "Done"
End If
End With
lvRequests.Items.Add(LVI)
lvcount += 1
End If
End While
End Using
There is not enough info to be really sure what is going on. It appears that you pull 10 columns from the DB, but if you only post 5 of them to the LV, then there should only be 5 subitems. So this is wrong:
If dr(9).ToString() = "DEMO" Then
lvRequests.Items(lvRequests.Items.Count - 1).SubItems(9).Text = "Done"
' should probably be:
If dr(9).ToString() = "DEMO" Then
lvRequests.Items(lvRequests.Items.Count - 1).SubItems(4).Text = "Done"
What might make it clearer at least in code would be to use Names for the subitems. If you instance a SubItem object rather than use a default constructor, you can assign a name and reference them that way instead:
Dim si As New ListViewItem.ListViewSubItem
With si
.Text = dr(X).ToString ' dunno whats in there
' this is probably not exactly right, but give the SubItem
' the same name as the db column
.Name = dr.Table.Columns(X).ColumnName
End With
thisItem.SubItems.Add(si) ' add sub to Item collection
Now, your code can use the name rather than index:
If dr(9).ToString() = "DEMO" Then
lvReq.Items(lvReq.Items.Count - 1).SubItems("TheColumnName").Text = "Done"
it no longer really matters how many columns or subitems there are. The ListViewItem.SubItems collection does not require sub item names to be unique, so it is possible to end up with 2 with the same name, but if you map from the DR/DT/DB correctly, it should take care of itself.
If the LV is bound to the datasource (you did not say), then there could be as many SubItems as db/datasource columns (never actually used an LV that way).