Getting data from a ListView into an array - vb.net

I have a ListView control on my form set up like this in details mode:
What I would like to do, is get all the values of the data cells when the user presses the Delete booking button.
So using the above example, my array would be filled with this data:
values(0) = "asd"
values(1) = "BS1"
values(2) = "asd"
values(3) = "21/04/2010"
values(4) = "2"
This is my code so far:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim items As ListView.SelectedListViewItemCollection = _
Me.ManageList.SelectedItems
Dim item As ListViewItem
Dim values(0 To 4) As String
Dim i As Integer = 0
For Each item In items
values(i) = item.SubItems(i).Text
i = i + 1
Next
End Sub
But only values(0) gets filled with the first data cell of the selection (in this case "asd") and the rest of the array entries are blank. I have confirmed this with a breakpoint and checked the array entries myself.
I'm REALLY lost on this, and have been trying for about an hour now. Any help would be appreciated, thanks :)
Also please note that there can only be one row selection at once. Thanks.

Costin is right about needing to iterate the subitems and if you're sure that there'll only be one selection iterating through the items just confuse things, I'd write it as:
Dim values As New List(Of String)
If ManageList.SelectedItems.Count > 0 Then
For Each item As ListViewItem.ListViewSubItem In ManageList.SelectedItems(0).SubItems
values.Add(item.Text)
Next
End If

I don't know how you populate the list but for me it seems that you need to iterate the item.Subitems to get the values. I don't know VB but I think you can use a something like :
For i As Integer = 0 To item.SubItems.Count
values(i) = item.SubItems(i).Text

Try this instead..
Dim values() As String
If items.Count = 1 Then
subitems = items(0).SubItems
ReDim values(0 To subitems.Count - 1)
For i As Integer = 0 To subitems.Count
values(i) = subitems(i).Text
Next
Else
Throw New Exception("boom")
End If

Related

How I can set the index of Datagridview to 0

How I can set the index of DataGridView to 0?
I developed a pharmacy software where I want to add values from TextBoxes into DataGridView with adding a new row. It is working but the problem is when I clear the value of DataGridView by using this code
dgvSoldMedicineInfo.Rows.Clear()
then when I try the previous procedure it show this error in VB.NET
Index was out of range, Must be non-negative and less than the size of the collection. Parameter name:index
Code:
Dim rowcounter As Integer = 0
Private Sub btnCalculate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate.Click
dgvSoldMedicineInfo.Rows.Add()
dgvSoldMedicineInfo.Rows(rowcounter).Cells("ColumnBarcodeNo").Value = txtBarcodeNo.Text
dgvSoldMedicineInfo.Rows(rowcounter).Cells("ColumnName").Value = dgvSale.CurrentRow.Cells(2).Value
dgvSoldMedicineInfo.Rows(rowcounter).Cells("ColumnQuantity").Value = txtQuantity.Text
dgvSoldMedicineInfo.Rows(rowcounter).Cells("ColumnSalePrice").Value = txtSalePrice.Text
dgvSoldMedicineInfo.Rows(rowcounter).Cells("ColumnAmount").Value = txtTotalAmount.Text
dgvSoldMedicineInfo.Rows(rowcounter).Cells("ColumnReject").Value = "Reject"
dgvSoldMedicineInfo.Rows(rowcounter).Cells("ColumnStockID").Value = dgvSale.CurrentRow.Cells(0).Value
dgvSoldMedicineInfo.Rows(rowcounter).Cells("ColumnStockQuantity").Value = dgvSale.CurrentRow.Cells(3).Value
System.Math.Max(System.Threading.Interlocked.Increment(rowcounter), rowcounter - 1)
End Sub
There's really no point to that rowcounter variable in that context and it's bad form to keep using dgvSoldMedicineInfo.Rows(rowcounter) over and over again. The proper way to do that would be like so:
Dim rowIndex = dgvSoldMedicineInfo.Rows.Add()
Dim row = dgvSoldMedicineInfo.Rows(rowIndex)
Dim cells = row.Cells
cells("ColumnBarcodeNo").Value = txtBarcodeNo.Text
cells("ColumnName").Value = dgvSale.CurrentRow.Cells(2).Value
'etc.
That said, why do that when the Add method is overloaded and will accept all the cell values up front?
dgvSoldMedicineInfo.Rows.Add(txtBarcodeNo.Text,
dgvSale.CurrentRow.Cells(2).Value,
...)

How to check if Variable value is increaseing vb.net?

Hi I have listview and lable ,the lable is showing how many items in the listview
I want if the lable is increased will show msgbox
* may be it will increased alot such as 100 or 1 whatever
* It will execute the command just one if the value is increased
* it must be execute the msgbox any time if the value is increased
I'm sorry for my bad language
thank you
the code :
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim b As String = New WebClient().DownloadString(TextBox2.Text + "/Getinfo.php")
Dim mc As MatchCollection = Regex.Matches(b, "(\w+):")
For Each x As Match In mc
Dim infoName As String = x.Groups(1).Value
Try
Dim download As String = New WebClient().DownloadString(TextBox2.Text + "/sender/info/" & infoName & "/info.txt")
Dim f As String() = download.Split(":")
Dim ls As New ListViewItem
ls.Text = infoName
For Each _x As String In f
ls.SubItems.Add(_x)
Next
Dim hTable As Hashtable = New Hashtable()
Dim duplicateList As ArrayList = New ArrayList()
Dim itm As ListViewItem
For Each itm In ListView1.Items
If hTable.ContainsKey(itm.Text) Then 'duplicate
duplicateList.Add(itm)
Else
hTable.Add(itm.Text, String.Empty)
End If
Next
'remove duplicates
For Each itm In duplicateList
itm.Remove()
Next
ListView1.Items.Add(ls)
'here I want to excute the command if the value is increased but it's timer and the code will be execute every time
Catch
End Try
Next
End Sub
At the top of your function do
Dim oldlength = ListView1.Items.Count
At the bottom do
If oldlength < ListView1.Items.Count Then
'here I want to excute the command if the value is increased
End If
I'm pretty sure that your MessageBox isn't really what you want but a debugging example because you think if you can get the MessageBox at the right time you've solved one of your problems (which is true).

VB.NET How to add Event Handler to ComboBoxColumn located in programmatically created controls?

I've got part of my code that creates a tab in a tabcontrol, and then fills it with a datagridview which contains a couple columns that are DataGridViewComboBoxColumn.
It looks like this:
Private Sub NewTabPage()
Dim TabPageCount As Integer = RacerOrderTAB.TabPages.Count
RacerOrderTAB.TabPages.Add(TeamNames(TabPageCount)) 'teamnames() is an array of team names
Dim CurrentTabPage = RacerOrderTAB.TabPages(TabPageCount)
Dim GridToAdd As New DataGridView
GridToAdd.Size = CurrentTabPage.Size
GridToAdd.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
GridToAdd.Location = New Point(CurrentTabPage.Location.X, CurrentTabPage.Location.Y)
GridToAdd.Columns.Add("ShiftCOL", "Shift Name")
GridToAdd.Name = "grid_" & CurrentTabPage.Text
For y As Integer = 1 To ShiftSetup.racerspershift 'add extra column for each racer in shift
Dim cmb As New DataGridViewComboBoxColumn
cmb.HeaderText = "Racer" & y
cmb.Name = "Racer_" & y
cmb.MaxDropDownItems = AmountOfRacers
cmb.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
GridToAdd.Columns.Add(cmb)
Next
RacerOrderTAB.TabPages(TabPageCount).Controls.Add(GridToAdd)
End Sub
But I've been having difficulty in adding an eventhandler for the comboboxes. What I want to happen is that when a combobox is clicked and opened, I populate it with the items I want.
I managed to vaguely get it working by adding:
AddHandler GridToAdd.EditingControlShowing, AddressOf <sub name>
but then have been unable to figure out which combobox was clicked, and how to populate it. It's also been requiring like four clicks before the drop list will appear. I'm only slightly very confused.
Thanks for any advice; these DataGridViewComboBoxColumns [deep breath] have been confusing me a lot!
It may be a little hacky but it should do what you are asking… hopefully. I created two List(Of String) variables. AllRacers contains all the racers… i.e. all the names we want to appear in a combo box such that there is no other combo box on that row that has an item selected. These names are what all combo boxes on all rows would initially contain in the selectable items list.
The other List(Of String) UsedRacers contains a list of all the “comboboxes” on the current row that have selected items. Each time a cell value is changed and it is one of the “combobox” column cells, then UsedRacers is cleared/updated to reflect the added/changed selected item on the current row.
When a “comboBox” cell value is changed, SetUsedRacersForRow is called…
Private Sub SetUsedRacersForRow(rowIndex As Int16)
UsedRacers.Clear()
Dim curValue = ""
For i = 1 To racersPerShift
If (Not (dgvRacers.Rows(rowIndex).Cells(i).Value Is Nothing)) Then
curValue = dgvRacers.Rows(rowIndex).Cells(i).Value.ToString()
If (Not (String.IsNullOrEmpty(curValue))) Then
UsedRacers.Add(curValue)
End If
End If
Next
End Sub
The code above loops through all the “combobox” cells in the given row and if a “combobox” cell has something selected, the selected value is added to the UsedRacers list.
Now that the selected items for all the “comboboxes” in that row are in the UsedRacers list, we can now loop through each “combobox” cell in that row and set the proper list of names. To help, a method is created that returns a DataGridViewComboBoxCell such that the names in the current UsedRacers list will NOT be in the DataGridViewComboBoxCell’s list of selectable names.
The only issue here would be with cells that currently have an item selected. Each “combobox” cell with an item selected will uniquely need to have its selected item in its list of items. To remedy this, a check is needed to see if the “combobox” cell contains a value. If the “combobox” cell DOES contain a selected value, then this value is also contained in the UsedRacers list. Since THIS cell is the cell that is in the UseRacers list… then we need to ADD this value to this cells items list. Otherwise, we would not be able to display the unique selection.
To keep the UsedRacers list consistent, we need to add this item directly to the individual “combobox” cell and not remove or alter the UsedRacers list as this will be used for the other “combobox” cells. In other words… whatever value is selected in a combo box, we need to make sure it is one of the items in the “combobox’s” list of selectable items. I hope that makes sense.
This can all be done in the DataGridViews CellChanged event.
Private Sub dgvRacers_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvRacers.CellValueChanged
If (e.ColumnIndex >= 1 And e.ColumnIndex <= racersPerShift) Then
SetUsedRacersForRow(e.RowIndex)
For i = 1 To racersPerShift
Dim newCell As DataGridViewComboBoxCell = GetCurrentComboBoxCell()
If (Not (dgvRacers.Rows(e.RowIndex).Cells(i).Value Is Nothing)) Then
Dim curValue = dgvRacers.Rows(e.RowIndex).Cells(i).Value.ToString()
newCell.Items.Add(curValue)
newCell.Value = curValue
End If
dgvRacers.Rows(e.RowIndex).Cells(i) = newCell
Next
End If
End Sub
In the code above, a method GetCurrentComboBoxCell (below) returns a DataGridViewComboBoxCell such that the items in the combo boxes list of items does not contain any items that are in the UsedRacers list. Because of this, a check is needed (above) to see if the cell already contains a value. NOTE: the DataGridViewComboBoxCell returned will always contain a “blank” empty item. This is necessary to allow the user to “De-Select” any currently selected value and then make the “De-Selected” item available to the other combo box cells.
Public Function GetCurrentComboBoxCell() As DataGridViewComboBoxCell
Dim newComboCell = New DataGridViewComboBoxCell()
newComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
newComboCell.FlatStyle = FlatStyle.Flat
newComboCell.Items.Add("")
For Each curRacer In AllRacers
If (Not UsedRacers.Contains(curRacer)) Then
newComboCell.Items.Add(curRacer)
End If
Next
Return newComboCell
End Function
Finally, putting all this together…
Dim racersInShift = 3
Dim AllRacers As List(Of String) = New List(Of String) From {"John", "Bobby", "Trent", "Josh", "Chapman", "Henry", "George", "Marvin"}
'Dim racersPerShift As Int16 = AllRacers.Count '<-- should be MAX value
Dim racersPerShift As Int16 = 4
Dim UsedRacers = New List(Of String)
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BuildGrid()
End Sub
Private Sub BuildGrid()
dgvRacers.Size = New Size(800, 200)
dgvRacers.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
'dgvRacers.Location = New Point(50, 200)
dgvRacers.Columns.Add("ShiftCOL", "Shift Name")
dgvRacers.Name = "RacersDGV"
dgvRacers.EditMode = DataGridViewEditMode.EditOnEnter
dgvRacers.AllowUserToAddRows = False
AddRacerColumns()
AddRacerRows()
End Sub
Private Sub AddRacerColumns()
Dim newColumn As DataGridViewComboBoxColumn
For i As Integer = 1 To racersPerShift
newColumn = GetNewComboBoxColumn("Racer" & i, "Racer " & i)
dgvRacers.Columns.Add(newColumn)
Next
End Sub
Private Sub AddRacerRows()
For i As Integer = 1 To racersInShift
Dim row As New DataGridViewRow
dgvRacers.Rows.Add(row)
Next
End Sub
Private Sub dgvRacers_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs)
‘See code above
End Sub
Private Sub SetUsedRacersForRow(rowIndex As Int16)
‘See code above
End Sub
Public Function GetCurrentComboBoxCell() As DataGridViewComboBoxCell
‘See code above
End Function
‘Lastly a method to set a whole `DataGridviewComboBoxColumn` which is used to initialize all the combo box columns
Public Function GetNewComboBoxColumn(colName As String, colHeader As String) As DataGridViewComboBoxColumn
Dim newComboCol = New DataGridViewComboBoxColumn()
newComboCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
newComboCol.FlatStyle = FlatStyle.Flat
newComboCol.Items.Add("")
newComboCol.HeaderText = colHeader
newComboCol.Name = colName
For Each curRacer In AllRacers
newComboCol.Items.Add(curRacer)
Next
Return newComboCol
End Function
I hope this helps, I am guessing there is an easier way to do this.

Storing a whole Array into a Session variable

Hei fellow Stackoverflowers,
I got a little problem with Session variables in VB.Net. I need to store a Array into a Session variable so that I can get the values back in another .aspx.vb. But somehow it won't work. If i try to read the values in the other page it's empty.
Here is my code for the checkboxes:
Private Sub chdBoxes()
Dim data()
Dim datacount As Integer
datacount = 0
ReDim data(GridView1.Rows.Count)
For Each row As GridViewRow In GridView1.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim chkRow As CheckBox = TryCast(row.Cells(0).FindControl("check1"), CheckBox)
If chkRow.Checked Then
Dim storeid As Integer = row.Cells(1).Text
data(datacount) = storeid
datacount = datacount + 1
End If
End If
Next
Session("rows") = GridView1.Rows.Count
Session("id") = data
End Sub
I appreciate every feedback and thank you for helping me out.
Greetings Soulrox

How to Set DataGridView Row Tag

I am using a double click event on a listview that will add three columns to a datagridview. I'm not sure how to set the "Tag" property on the "selectedText" variable.
Private Sub lwArticles_DoubleClick(sender As Object, e As System.EventArgs) Handles lwArticles.DoubleClick
Dim selectedText = lwArticles.SelectedItems(0).SubItems.Item(0).Text 'Article No
Dim selectedDesc = lwArticles.SelectedItems(0).SubItems.Item(1).Text 'Description
Dim currRowNo As String = ""
Dim alreadyExists = False
For i As Integer = 0 To dgvDetail.Rows.Count - 1
currRowNo = dgvDetail.Rows(i).Cells(0).Value
If currRowNo = selectedText Then
alreadyExists = True
dgvDetail.Rows(i).Cells(2).Value += 1
Exit For
End If
Next
'If the entry doesn't exist, add it
If Not alreadyExists Then
dgvDetail.Rows.Add(New String() {selectedText, selectedDesc, 1})
End If
End Sub
After this I loop through the row's tags to see the article numbers. It will be near my dgvDetail.Rows.Add() that I should be setting the Tag property to equal the selectedText ... Any one know how to do this?
Edit:
The datagridview columns being populated are: "Article Number", "Description" and "Quantity". The quantity is set in the loop, basically if I've double clicked on the same thing twice, it will increment the third column (Cell(2)) by one.
The Add "function" for the DataGridView control returns the index of the row in the grid, so you can try using that to reference the row:
Dim rowIndex As Integer
rowIndex = dgvDetail.Rows.Add(New String() {selectedText, selectedDesc, 1})
dgvDetails.Rows(rowIndex).Tag = selectedText