Getting ListView values into a string array? - arrays

I have a ListView control set up in details mode, and on a button press I would like to retrieve all column values from that row in the ListView.
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(1).Text
i = i + 1
Next
End Sub
But values just comes out as an empty array. Any ideas? I just want the values array to be filled with the data of that ListView row.
Cheers.

Here's the single-line solution:
mylistview.Items.Cast(Of ListViewItem).Select(Function(lvi As ListViewItem)lvi.SubItems(1).Text).ToArray()

You need to iterate the SubItems, not the selected items. Fix:
If Me.ManageList.Items.Count <> 1 Then Exit Sub
Dim row As ListViewItem = Me.ManageList.Items(0)
Dim values(0 To row.SubItems.Count-1) As String
Dim i As Integer = 0
For Each item As ListViewItem.ListViewSubItem In row.SubItems
values(i) = item.Text
i = i + 1
Next

Just to check, are you aware that item.SubItems(1).Text will get the texts from the second column? And that since you're using SelectedItems it'll only look at the currently selected items in the ListView.
Edit:
Also, are you sure there will always just be a maximum of 5 selected items in the ListView?
Otherwise you'll have problems with
Dim values(0 To 4) As String

Old question, I know... maybe this helps for someones reference.. stumbled upon this question in a search for something else.
This works... not sure if the original poster somehow used an empy colelciton of selected items...
Also, dynamically resizing array based on selected items to overcome unforseen bugs...
Dim valueArray(mylistview.SelectedItems.Count - 1) As String
Dim i As Integer
For Each Item As ListViewItem In mylistview.SelectedItems
valueArray(i) = Item.Text
i += 1
Next
To get subitems, use item.subitems(1).text ... subitems(2).text.. etc
Cheers

Related

Excel VBA pass multiple Combobox values to dynamic array

I would like to know if there is a way to add selected multiple combo box values to a dynamic array. So far this my code below, at the moment I can only submit the one selected Combobox value to the array list.
Private Sub UserForm_Initialize()
ComboBox1.AddItem "1"
ComboBox1.AddItem "2"
ComboBox1.AddItem "3"
End Sub
Private Sub CommandButton1_Click()
Dim cmbbox(10) As String
Dim i As Integer
For i = LBound(cmbbox) To UBound(cmbbox)
cmbbox(i) = ComboBox1.Value
MsgBox cmbbox(i)
Next i
End Sub
I would like to be able to select a value from the combo box, and then that value gets passed to my array at the 0 position, and then if the another value is selected from the combo box, then that value is passed to my array's 1 position etc...
This should do:
For Each Item In ComboBox1.List
If Not Item Then
MsgBox Item
End If
Next
Edit: Did I miss your point here, or did you change your question? According to what I read now, you want to append combobox value at the end of your array each time you hit commandbutton. You should do as follows:
Define your array outside of your sub (at the very top):
Dim cmbbox() As Variant
and the code should look like:
Private Sub CommandButton1_Click()
If Len(Join(cmbbox, "")) = 0 Then 'if your array is empty add the first value from combobox
ReDim cmbbox(0)
cmbbox(0) = ComboBox1.Value
Else 'if your array is not empty redim your array and add value from combobox
ReDim Preserve cmbbox(UBound(cmbbox) + 1)
cmbbox(UBound(cmbbox)) = ComboBox1.Value
End If
MsgBox "Last Added Item : " & cmbbox(UBound(cmbbox))
End Sub
As #Tehscript has indicated, the property you're after is .List which returns a two-dimensional, zero-based array: the first dimension being 'rows' and the second 'columns'.
From your question, it seems as if you want a specific index (or indices) from the row dimension. If your ComboBox only has one column then the second dimension could be hard-coded as zero.
A For Each loop would be okay, but the problem is that it will loop through every item in the array rather than just each row. It might be more efficient, therefore, to run a For [index] loop. Let's say you want the first and third items in your ComboBox, then the code snippet would be:
Dim i As Long
Dim v As Variant
v = ComboBox1.List
For i = 0 To UBound(v, 1)
If i = 0 Or i = 2 Then
MsgBox v(i, 0)
End If
Next

Select items in listbox from array

I currently have a cell with a list separated by commas (1, 2, 3) and the list isn't always the same amount of items. It can be up to 10 items.
I then have a listbox with items 1 - 10 in it.
I want to be able to select the specific items that are in the cell on a form with the listbox on it.
I have started by splitting the cell into an array like this:
Dim Array() As String
Array= Split(ActiveSheet.Range("A1"), ",")
But I can't figure out how to select items in my listbox that match the array.
Try the below Code. I tested it. It worked fine for me.
Sub formdisplay()
Dim valsToSelect
valsToSelect = Split(Range("E6").Value, ",") 'E6 is my cell where i have my value in the form of 5,6,7,9
For Each item In valsToSelect
i = 0
For Each listItem In UserForm1.ListBox1.List
If CStr(listItem) = item Then
UserForm1.ListBox1.Selected(i) = True
Exit For
End If
i = i + 1
Next
Next
UserForm1.Show
End Sub

create array of existing buttons vb 2013

I used to program in VB6 and am trying to write the same program in VB 2013. In this program I use an array of 49 buttons that all do the same thing when you click on them. I have figured out have to do the click function to a point:
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button9.Click, Button10.Click, Button11.Click, Button12.Click, Button13.Click, Button16.Click, Button17.Click, Button18.Click, Button19.Click, Button20.Click
...
End Sub
What I am trying to do is simplify the code down to using an array so I can just pass on the index. One other person asked the same question in 2010 and the best answer was:
Button[] array = { firstButton, secondButton };
That would work but I want something with less typing. I also tried the following with failure:
One
Button[] buttons = this.Controls.OfType<Button>().ToArray();
Two
For i = 1 To 100
Dim btns() As Button = Controls.Find("Button" & i, True)
Dim btn As Button
If btns IsNot Nothing Then
btn = btns(0)
'If buttons Is Nothing Then
' ReDim buttons(0)
'Else
' ReDim Preserve buttons(buttons.Length)
'End If
'buttons(UBound(buttons)) = btn
btn.Text = i - 1 'here you can change whatever you want
End If
Next
Three
Dim buttons() As Button
buttons = Nothing
For Each b As Button In Me.Controls
If buttons Is Nothing Then
ReDim buttons(0)
Else
ReDim Preserve buttons(buttons.Length)
End If
buttons(UBound(buttons)) = b
Next
I just can't get it to accept the existing buttons into an array. I hope someone can help.
If your Buttons are nested inside container controls (e.g. a GroupBox) then you will need to perform a recursive search for all buttons. Maybe something like this (totally unoptimized)...
Private Function FindAllButtons(root As Control) As List(Of Button)
Dim result As List(Of Button) = New List(Of Button)()
For Each c As Control In root.Controls
If TypeOf c Is Button Then
result.Add(DirectCast(c, Button))
ElseIf c.HasChildren Then
result.AddRange(FindAllButtons(c))
End If
Next
Return result
End Function
Then just call that in your Form:
Dim allButtons as List(Of Button) = FindAllButtons(Me)
' Add common Click handler
For Each b As Button In allButtons
AddHandler b.Click, AddressOf Button_Click
Next
Update Just for fun, here's a generic version to find other types of control.
Private Function FindAllControls(Of T As Control)(root As Control) As List(Of T)
Dim result As List(Of T) = New List(Of T)()
For Each c As Control In root.Controls
If TypeOf c Is T Then
result.Add(DirectCast(c, T))
ElseIf c.HasChildren Then
result.AddRange(FindAllControls(Of T)(c))
End If
Next
Return result
End Function
You can use that like:
Dim allButtons As List(Of Button) = FindAllControls(Of Button)(Me)
Dim allTextBoxes As List(Of TextBox) = FindAllControls(Of TextBox)(Me)
Option two will work, you just need to add the button found into a list. I suggest you add your buttons into a List(Of ) instead of an array. You can always convert the list into an array if you really need to.
Dim buttonList As New List(Of Button)
For i As Integer = 1 To 100
Dim btns() As Control = Controls.Find("Button" & i, True)
If btns IsNot Nothing AndAlso btns.Length > 0 Then
buttonList.Add(CType(btns(0), Button))
End If
Next

remove bulletstyle on WPF richtextbox selection

I've managed to applying bulleted list formatting possible, but how to remove it again?
How to detect if the selection is/contains a List?
Did I overcomplicate things? Is there a straightword way to convert a selection to a bulleted list and back?
Private Sub bullet(o As Windows.Forms.ContextMenuStrip, e As Windows.Forms.ToolStripItemClickedEventArgs)
Dim lst As New Windows.Documents.List()
lst.MarkerStyle = bullets(e.ClickedItem.Text)
If rtf.Selection.IsEmpty Then
lst.ListItems.Add(New Windows.Documents.ListItem())
Else
Dim li As Windows.Documents.ListItem
Dim lines() As String = rtf.Selection.Text.Split(vbCrLf)
For Each s As String In lines
li = New Windows.Documents.ListItem()
li.Blocks.Add(New Windows.Documents.Paragraph(New Windows.Documents.Run(s.Trim())))
lst.ListItems.Add(li)
Next
rtf.Selection.Text = ""
End If
Dim curCaret = rtf.CaretPosition
Dim curBlock = rtf.Document.Blocks.Where(Function(x) x.ContentStart.CompareTo(curCaret) = -1 AndAlso x.ContentEnd.CompareTo(curCaret) = 1).FirstOrDefault()
rtf.Document.Blocks.InsertAfter(curBlock, lst)
Dim vMove As Windows.Documents.TextPointer = Nothing
vMove = curCaret.GetNextInsertionPosition(Windows.Documents.LogicalDirection.Forward)
If vMove IsNot Nothing Then rtf.CaretPosition = vMove
rtf.Focus()
End Sub
I've since come to drop this code from my project because it's unreliable in certain situations. Would a solution based on dynamic XAML insertion be more reliable? Many aspects of WPF seem to very poorly conceived....
If you could use the windows forms version of richtextbox, you could use the SelectionBullet property.
http://msdn.microsoft.com/en-us/library/ms742875.aspx
Try EditingCommands.ToggleBullets.Execute(null, richTextBox) to toggle bullet style in selected paragraphs.

Datagrid row hiding, in wpf vb.net

The problem is that i need to hide some rows of the DataGrid, based on which monitor they are displayed.
Here is my code:
For Each row As DataRowView In DataGrid1.Items
cellValue = row.Item("Monitor")
If cellValue.StartsWith("B") Then
//the code i need
End If
Next
The DataGrid1.Items.Remove() or DataGrid1.Items.RemoveAt() can't be used, cause my ItemSource is in use when they are called.
I prefer changing its visibility to hidden or height to 0.
Sorry if this question is not in the right format or looks bad, this is my first one :P (any tips are welcome)
Thanks in advance
This should work for you:
row.Visibility = Windows.Visibility.Collapsed
P.S.:
In my scope the DataGrid was bound to a List(Of String) so i had to get that row first. So when using
DataGrid.Items(i) you will only get the item itself which was a String.
To get the related DataGridRow you have to use this function:
DataGrid.ItemContainerGenerator.ContainerFromIndex(IndexOfItem)
Changed my code to:
Dim numOfRows As Integer
Dim listA As New List(Of Integer)
Dim listB As New List(Of Integer)
Dim deleted As Integer = 0
For Each row As DataRowView In DataGrid1.Items
numOfRows += 1 'Adding up to total number of rows'
If row.Item("Monitor").ToString.StartsWith("A") Then
listA.Add(numOfRows - 1) 'Adding rows indexes to a list'
ElseIf row.Item("Monitor").ToString.StartsWith("B") Then
listB.Add(numOfRows - 1) 'Adding rows indexes to a list'
End If
Next
The reason i didn't use row.Delete() is because the For Each loop breaks if i change its item source on the run. Thus, I'm deleting the rows on another loop (one for each monitor):
Dim rowA As DataRowView
For Each litem As Integer In listA
litem -= deleted
'The indexes on the list were added in a sorted order'
'ex. {4,7,14,28,39} . So if i delete the fourth row'
'all of the rows that remain will have their index'
'decreased by one,so by using an integer that represents'
'the number of the deleted rows, i can always delete the'
'correct "next" row'
rowA = DataGrid1.Items.Item(litem)
rowA.Delete()
deleted += 1
Next

Resources