VB.NET: How to dynamically select a list view item? - vb.net

I need to dynamically select an item in a listview based on what was selected previously.
The items that have been selected in the past are retrieved from a database and added to an Arraylist. These items then need to be selected from a number of different listviews.
Doing this by index like so listRef1.Items(2).Checked = True is no problem but I need to do it by the item text, i.e. one of the strings in the array.
So far I have this:
For i As Integer = 0 To refsArr.Count - 1
'find the correct category id
Dim cmdRefCat As New SqlCommand("SELECT RefID from ReferencesListTable WHERE RefName = '" & refsArr(i) & "'", conn)
Dim refid As Integer = cmdRefCat.ExecuteScalar()
If refid = 1 Then
listRef1.Items(refsArr(i)).Checked = True
ElseIf refid = 2 Then
listRef2.Items(refsArr(i)).Selected = True
listRef2.Select()
ElseIf refid = 3 Then
listRef3.Items.Item(refsArr(i)).Selected = True
listRef2.Select()
ElseIf refid = 4 Then
listRef4.Items.Item(refsArr(i)).Selected = True
End If
Next
Has anyone got any ideas on this? Thanks.

You'll need to loop through each item in the listview list:
For I as Integer = 0 to ListView.Items.Count - 1 Do
If ListView.Items(i).Text = "Text" then
ListView.Items(i).Selected = true
End If
End For

You can try this ...
For i As Integer = 0 To refsArr.Count - 1
'find the correct category id
Dim cmdRefCat As New SqlCommand("SELECT RefID from ReferencesListTable WHERE RefName = '" & refsArr(i) & "'", conn)
Dim refid As Integer = cmdRefCat.ExecuteScalar()
Select case refid
case 1
CheckIt(refsArr(i),listRef1)
case 2
CheckIt(refsArr(i),listRef2)
case 3
CheckIt(refsArr(i),listRef3)
case 4
CheckIt(refsArr(i),listRef4)
End Select
Next
And Sub CheckIt
Sub CheckIt(ByVal sRef as String, ByRef lvw as Listview)
Dim x as Integer
For x = 0 to lvw.Items.Count - 1
If lvw.Items(x).Text = sRef then
lvw.Items(x).Selected = true
exit for '-- if only 1 record
End If
Next
End Sub

The code to select an item dynamically from the listview control can be as follows for vb.net.
Let lvwomominiChair1 is the name of the listview control.
Set its fullrowselect property as true.
The code will select the text in the first column of the listview control.
Private Sub lvwomominiChair1_Click(sender As Object,e As EventArgs) Handles lvwomominiChair1.Click
Dim lvwitem as ListViewItem
lvwitem = lvwomominiChair1.SelectedItems.Item(0)
MsgBox("Selected item is " + lvwitem.Text)
End Sub
There may be situations where we need to get all items in a row of a ListView control.The following code may be used for the purpose.It is assumed that there are five columns of data in a raw and are of the text data type.This can be done with a For..Next loop as follows.Let 0,1,2,3 and 4 are the five column indices.
Private Sub lvwomominiChair1_Click(sender As Object,e As EventArgs) Handles lvwomominiChair1.Click
Dim i As Int32
Dim str As String
str =""
For i =0 To 4
str = str + " " + lvwomominiChair1.SelectedItems(0).SubItems(i).Text
Next
MsgBox("Selected items of the five columns of the row are " + str)
End Sub

Or you can do this, works perfect for me:
ListView.Items(0).Selected = True
ListView.Select()

Related

prevent go to next row when duplicated value in `datagridview`

I have datagrid that user will add values in just one column , and i want to prevent duplicated data in this column, i had mange that by the code bellow,
what I want is to keep the selection (focus) in the same editing cell(x)
if the entered data is duplicated, so I tried to get the current row index and return to it if the data is duplicated but its not working.
row_index = DataGridView1.CurrentRow.Index.ToString()
Dim cell As DataGridViewCell = DataGridView1.Rows(row_index).Cells(1)
DataGridView1.CurrentCell = cell
DataGridView1.BeginEdit(True)
NOTE : User will Add barcode number, so he will use barcode scanner or add it manually and press enter key.
Private Sub DataGridView1_RowValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.RowValidated
If DataGridView1.Rows.Count > 2 Then
Dim i As Integer = 0
Dim row_index As Integer
' loop condition will loop while the row count is less or equal to i
While i <= DataGridView1.Rows.Count - 1
Dim j As Integer = 1
' loop condition will loop while the row count is less or equal to j
While j <= DataGridView1.Rows.Count - 1
Dim str As String = DataGridView1.Rows(i).Cells(1).Value()
Dim str1 As String = DataGridView1.Rows(j).Cells(1).Value()
If Not str1 = "" AndAlso Not str = "" Then
If str1 = str Then
'row_index = DataGridView1.SelectedCells.Item(i).RowIndex.ToString()
row_index = DataGridView1.CurrentRow.Index.ToString()
Dim cell As DataGridViewCell = DataGridView1.Rows(row_index).Cells(1)
DataGridView1.CurrentCell = cell
DataGridView1.BeginEdit(True)
Exit Sub
End If
End If
j += 1
End While
i += 1
End While
End If
End Sub
You can try it also in a for loop. This is how I do it. If what you mean is to stop/retain the selection(focus) or go to in a cell/row whenever it is a duplicate with the current data you have. This should work fine.
enter code here
For i = 0 To Datagridview1.Rows.Count - 1
If Datagridview1.Rows(i).Cells(1).Value = DataYouWillInput Then
DataGridView1.CurrentCell = DataGridView1.Rows(i).Cells(1)
Exit for
End If
Next
enter code here
If your condition returns true with the condition of current data and data you'll be adding. Just exit your loop. Use this.
DataGridView1.CurrentCell = DataGridView1.Rows(i).Cells(1)

ArgumentOutOfRangeException was Unhandled , Index was out of range

I want to ask if anyone knows this why this error occurs? So there are 2 forms. The first calculation form there is no error and this is the second calculation form which produces the error, after searching here and there masi not yet enlightenment, maybe someone can help?
THIS SCREENSHOT OF ERROR
this full source code
Public Class FrmHitung2
Private Sub FrmHitung2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim dt As DataTable = openDT("SELECT * FROM tb_rel_alternatif2 WHERE kode_crips NOT IN (SELECT kode_crips FROM tb_crips2)")
If dt.Rows.Count > 0 Then
msgError("Anda belum mengatur nilai untuk setiap alternatif, silahkan atur di menu Nilai Bobot")
BtnCetak.Enabled = False
Else
Dgv1.AllowUserToAddRows = False
Dgv1.AllowUserToDeleteRows = False
Dgv1.ReadOnly = True
Dgv1.AutoGenerateColumns = False
awal()
End If
End Sub
Sub awal()
Dgv1.Columns.Clear()
Dgv1.Rows.Clear()
Dgv1.Columns.Add("nim", "Kode")
Dgv1.Columns("nim").ReadOnly = True
Dgv1.Columns.Add("nama_mahasiswa", "Nama")
Dgv1.Columns("nama_mahasiswa").ReadOnly = True
dr = openDR("SELECT * FROM tb_alternatif2 ORDER BY nim")
While dr.Read()
Dgv1.Rows.Add(dr(0), dr(1))
End While
dr = openDR("SELECT kode_kriteria, atribut FROM tb_kriteria2 ORDER BY kode_kriteria")
While dr.Read()
Dgv1.Columns.Add(dr(0), dr(0))
Dgv1.Columns(dr(0).ToString()).ToolTipText = dr(1).ToString()
End While
For a = 0 To Dgv1.Rows.Count - 1
dr = openDR("SELECT c.nama_crips FROM tb_rel_alternatif2 r " &
" LEFT JOIN tb_crips2 c ON c.kode_crips = r.kode_crips " &
" WHERE nim='" & Dgv1.Rows(a).Cells(0).Value & "' ORDER BY r.kode_kriteria")
Dim b As Integer = 2
While dr.Read
Dgv1.Rows(a).Cells(b).Value = dr(0)
b = b + 1
End While
Next
Dgv1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
BtnCetak.Enabled = False
End Sub
Function get_col_max(ByVal dgv As DataGridView, ByVal col_name As String) As Double
Dim max As Double = 0
If dgv.Rows.Count > 0 Then max = Val(dgv.Rows(0).Cells(col_name).Value)
For Each row As DataGridViewRow In dgv.Rows
If Val(row.Cells(col_name).Value) > max Then
max = Val(row.Cells(col_name).Value)
End If
Next
get_col_max = max
End Function
Function get_col_min(ByVal dgv As DataGridView, ByVal col_name As String) As Double
Dim min As Double = 0
If dgv.Rows.Count > 0 Then min = Val(dgv.Rows(0).Cells(col_name).Value)
For Each row As DataGridViewRow In dgv.Rows
If Val(row.Cells(col_name).Value) < min Then
min = Val(row.Cells(col_name).Value)
End If
Next
get_col_min = min
End Function
Private Sub BtnHitung_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnHitung.Click
Dim a, b As Integer
awal()
Dgv1.copyTo(Dgv2)
For a = 0 To Dgv2.Rows.Count - 1
dr = openDR("SELECT c.nilai FROM tb_rel_alternatif2 r " &
" LEFT JOIN tb_crips2 c ON c.kode_crips = r.kode_crips " &
" WHERE nim='" & Dgv2.Rows(a).Cells(0).Value & "' ORDER BY r.kode_kriteria")
b = 2
While dr.Read
Dgv2.Rows(a).Cells(b).Value = dr(0)
b = b + 1
End While
Next
Dgv2.copyTo(Dgv3)
For Each row As DataGridViewRow In Dgv2.Rows
For b = 2 To Dgv2.Columns.Count - 1
Dim v = row.Cells(b).Value
If Dgv2.Columns(b).ToolTipText = "benefit" Then
Dgv3.Rows(row.Index).Cells(b).Value = v / get_col_max(Dgv2, Dgv2.Columns(b).Name)
Else
Dgv3.Rows(row.Index).Cells(b).Value = get_col_min(Dgv2, Dgv2.Columns(b).Name) / v
End If
Next
Next
dr = openDR("SELECT kode_kriteria, bobot FROM tb_kriteria2 ORDER BY kode_kriteria")
While dr.Read()
Dgv3.Columns(dr(0).ToString()).ToolTipText = dr(1).ToString()
End While
Dgv3.copyTo(Dgv4)
For Each row As DataGridViewRow In Dgv3.Rows
For b = 2 To Dgv3.Columns.Count - 1
Dim v = row.Cells(b).Value
Dgv4.Rows(row.Index).Cells(b).Value = v * Val(Dgv3.Columns(b).ToolTipText)
Next
Next
Dgv4.Columns.Add("total", "Total")
For Each row As DataGridViewRow In Dgv4.Rows
For b = 2 To Dgv2.Columns.Count - 1
row.Cells("total").Value = row.Cells("total").Value + row.Cells(b).Value
Next
Next
Dgv4.copyTo(Dgv5)
Dgv5.Sort(Dgv5.Columns("total"), System.ComponentModel.ListSortDirection.Descending)
For Each row As DataGridViewRow In Dgv5.Rows
execute("UPDATE tb_alternatif2 SET total=#0, rank=#1 WHERE nim=#2", row.Cells("total").Value, row.Index + 1, row.Cells("nim").Value)
Next
TabControl1.SelectedTab = TabRangking
BtnCetak.Enabled = True
End Sub
Private Sub BtnCetak_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnCetak.Click
LapRangking.ShowAsChild(Me.MdiParent)
End Sub
Private Sub BtnKeluar_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnKeluar.Click
Me.Close()
End Sub
End Class
Why are your using dr.Read() at one place and dr.Read in another. Underlined in RED. Maybe the DataReader is not populated yet!, It should be dr.Read()
That error occurs when you try to access an array or other collection with an index that doesn't exist. Note that indexing starts at 0 all the way to Count - 1.
From you screenshot I can see the error occurs at this line Dgv1.Rows(a).Cells(b).Value = dr(0). a is defined in a For loop this way, For a = 0 To Dgv1.Rows.Count - 1 so it is unlikely that is the culprit.
You may want to check the value of b which you have started with a value of 2. If you're trying to access the second item in the collection, you will have to change that line to read...
Dim b As Integer = 1 ' If you wanted to start from the 2nd cell.
While dr.Read
Dgv1.Rows(a).Cells(b).Value = dr(0)
b = b + 1
End While
b is likely growing past the number of cells you have and causing that problem.
Note: I have changed the definition of b to start at 1
Update 2
After looking at your code again, I'm seeing something that I seem to have missed when looking at line that caused the error. You are defining b as, Dim b As Integer = 2 ' I recommended changing that to 1 and using it to access the columns in your dataset/reader. But when I look at your queries, something else reveals itself. The 1st one in the awal() method is
SELECT * FROM tb_alternatif2 ORDER BY nim
which returns an ordered set with an unknown (to me anyway) number of rows and columns. You are then looping through adding the 1st and 2nd columns of the data reader to rows of what I assume is a data grid view. After that, you make a call to another query
SELECT kode_kriteria, atribut FROM tb_kriteria2 ORDER BY kode_kriteria
which returns an ordered set with 2 columns that you add as columns to the data grid view. Next you have the query
SELECT c.nama_crips FROM tb_rel_alternatif2 r --... truncated
which returns one column which is when you are defining b. Somewhere between the number of columns you are creating and then addressing them with b, you are probably hitting an off by one error. Or more than off by one. Assuming the 2nd query creates for you 10 columns and the third query returns 15 rows, you will quickly run out of columns to address using .Cells(b).Value in your code.
It is unclear to me what you are trying to do with this, but I would recommend trying to define your query again and binding once to the data grid. As an aside: I would also recommend using parameters for constructing your queries because the way you have done isn't too secure... SQL injection and all that.

how to check checklistbox items using datagridview vb.net?

I'm just a beginner for coding and I want to programmatically check items in checklistbox using datagridview.
Data grid view values are seperated with commas like this jhon,Metilda,saman,.
Checklistbox name as chklistinput and please help me to solve this ?
'Full coding is here..............................
Private Sub TextBox10_TextChanged(sender As Object, e As EventArgs) Handles TextBox10.TextChanged
'this is ok and searching as I want
Dim SearchV As String = TextBox10.Text
SearchV = "%" + TextBox10.Text + "%"
Me.PassIssuingRecordTableAdapter.FillBy(Me.Database4DataSet.PassIssuingRecord, SearchV)
'But the problem bigins here
Dim areasback As String = DataGridView1.Rows(0).Cells(6).Value.ToString
Dim areasback1 As String() = areasback.Split(",")
For Each x In areasback1
For i = 0 To areasback.Count - 1
If chklistInput.Items(i).ToString() = x.ToString() Then
chklistInput.SetItemChecked(i, False)
End If
Next
Next
End Sub
You have to loop over chklistInput.Items.Count - 1 instead of areasback.Count - 1
use the following code:
Dim areasback As String = DataGridView1.Rows(0).Cells(6).Value.ToString
Dim areasback1 As String() = areasback.Split(",")
Dim intCount as integer = 0
For each str as string in areasback1
For intCount = 0 To chklistInput.Items.Count - 1
If chklistInput.Items(intCount).ToString() = str Then
chklistInput.SetItemChecked(intCount , True)
End If
Next
Next
chklistInput.Refresh()
Note: comparing is case sensitive

Checking existing database record items against listbox items

I have a datatable that I am adding records to in my windows forms application. this datatable only has 2 columns and the first column is the primary key and is an integer. The second column contains names and I need to automatically add a list of names from a listbox to the table. Most of these names will already have their own record in the table but there will be different names in the listbox each time. I need to check the existing record items against the listbox items to make sure no duplicates get added, but if there is a name in the listbox that does not exist in the datatable, add a new record for that name.
What I have tried so far is this:
Private m_cn As New SqlConnection()
Private m_DA As SqlDataAdapter
Private m_CB As SqlCommandBuilder
Private m_DataTable As New DataTable
Private m_IntRowPosition As Integer = 0
Private Sub btnInsertIntoDatabase_Click(sender As Object, e As EventArgs) Handles btnInsertIntoDatabase.Click
Dim drReadRow As DataRow = m_DataTable.NewRow()
Dim dcReadCol As DataColumn = m_DataTable.Columns.Item(1)
Dim intLoopCounter As Integer = 0
Dim unique As Boolean = True
If m_DataTable.Rows.Count = 0 Then
For m_IntRowPosition = 0 To (lstScannedNames.Items.Count() - 1)
Dim drNewRow As DataRow = m_DataTable.NewRow()
drNewRow("emp_id") = m_IntRowPosition
drNewRow("emp_name") = RTrim(lstScannedNames.Items.Item(RTrim(m_IntRowPosition)))
m_DataTable.Rows.Add(drNewRow)
Next m_IntRowPosition
GoTo SomeWhereElse
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
ElseIf m_DataTable.Rows.Count > 0 Then
For m_IntRowPosition = 0 To m_DataTable.Rows.Count
For intLoopCounter = 0 To lstScannedNames.Items.Count - 1
If RTrim(m_DataTable.Rows(m_IntRowPosition).Item(1)) = lstScannedNames.Items.Item(intLoopCounter) Then
unique = False
ElseIf RTrim(m_DataTable.Rows(m_IntRowPosition).Item(1)) <> lstScannedNames.Items.Item(intLoopCounter) Then
unique = True
lstScannedNames.SelectedIndex = intLoopCounter
intLoopCounter = lstScannedNames.Items.Count - 1
End If
Next intLoopCounter
If (unique) = True Then
Dim drNewRow As DataRow = m_DataTable.NewRow()
drNewRow("emp_id") = m_DataTable.Rows.Count()
drNewRow("emp_name") = lstScannedNames.Items.Item(lstScannedNames.SelectedIndex)
m_DataTable.Rows.Add(drNewRow)
Else
unique = True
End If
Next m_IntRowPosition
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
End If
SomeWhereElse:
m_DA.Update(m_DataTable)
MessageBox.Show("Operation Completed")
End Sub
The area of focus is the ElseIf statement. When I run this code and there are already records in the database, it adds the first name that is in the list and not in the datatable, to the datatable. It then adds the first name from the list to a new record, for each item in the list, which is about 20 times but it depends on the list length. I've been trying different things and I know I'm close but I've been stuck for a while.
Reverse your logic. Loop over the items in the listbox and check if they are present in the datatable
....
For intLoopCounter = 0 To lstScannedNames.Items.Count - 1
Dim name = lstScannedNames.Items.Item(intLoopCounter)
Dim rowExist = m_DataTable.Select("emp_name = '" & name & "'")
if rowExist Is Nothing OrElse rowExist.Length = 0 Then
Dim drNewRow As DataRow = m_DataTable.NewRow()
drNewRow("emp_id") = m_DataTable.Rows.Count()
drNewRow("emp_name") = name
m_DataTable.Rows.Add(drNewRow)
End If
Next m_IntRowPosition
...
Using the DataTable.Select method avoids to write an explicit loop to find the duplicate. And you can directly add the row when you are certain that there is no duplicate

How to concat variable integer in control name in vb.net

Now I have a database and pull out that data and display it to form,i have a sequence of groupbox and radiobuttons, in each groupbox (groupbox1,groupbox2,etc...) there are 2 radio buttons namely rdbtn1Yes and rdbtn1No (then it increment +1 in next Groupbox). now i use for loop to go through every groupboxes and radio buttons. And this is my code:
Dim sqlda As New SqlDataAdapter("SELECT * FROM table1 WHERE column1= '" & lblWONo.Text & "'", Constr)
Dim sqlds As New DataSet
sqlds.Clear()
sqlda.Fill(sqlds)
If sqlds.Tables(0).Rows.Count > 0 Then
With sqlds.Tables(0).DefaultView.Item(0)
txtDateCreated.Value = .Item(0).ToString
txtComments.Text = .Item(1).ToString
'check column if it contain FALSE/TRUE value
'then toggle the radiobutton state to TRUE
'In this part i know there is another/easiest way to checked radio buttons to TRUE value
'and this is my code using looping (below):
If .Item(2) = False Then
rdbtn1No.Checked = True
Else
rdbtn1Yes.Checked = True
End If
If .Item(3) = False Then
rdbtn2No.Checked = True
Else
rdbtn2Yes.Checked = True
End If
If .Item(4) = False Then
opt3N.Checked = True
Else
opt3Y.Checked = True
End If
End With
End If
SAMPLE CODE FOR LOOPING:
Dim itemNo As Integer
Dim rdbtnSet As Integer = 1
Dim grpboxCnt As Integer = 1
For Each grpbx As GroupBox In Me.Controls.OfType(Of GroupBox)()
For itemNo = 2 To sqlds.Tables(0).Columns.Count
If .Item(itemNo) = True Then
rdbtn & rdbtnSet & "Yes".checked = True 'I want to be this way but we know that this is not working or its not the proper way. That is my problem.
Else
rdbtn & rdbtnSet & "No".checked = True 'I want to be this way but we know that this is not working or its not the proper way. That is my problem.
End If
Next
rdbtnSet += 1
grpboxCnt += 1
Next
Thats all. Thank you in advance!
Think about the use of a dictionary (id, control) to store your controls. Then iterate the dictionary and set your state.