Dividing listbox items into 2 parts - vb.net

I have a listbox with random items, I wanted to divide it into 2 part's and put each part in one listbox. I was able to do it, but i got a very messy code, couldn't found any help online, so I just wanna to ask if there is another way of doing it. Here's my code.
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
'items count
Dim count_listbox1 As Integer = ListBox1.Items.Count - 1
'half the count - 1 (im going to use it on the for loop)
Dim metade_listbox1_1 As Integer = (count_listbox1 / 2) - 1
'half the count
Dim metade_listbox1_2 As Integer = (count_listbox1 / 2)
' ( first part of the listbox)
For i = 0 To metade_listbox1_1
list1.Items.Add(ListBox1.Items.Item(i)) 'list1 - listbox that contains 1 half
Next
' (second part of the listbox items)
For i = metade_listbox1_2 To count_listbox1
list2.Items.Add(ListBox1.Items.Item(i)) 'list2 - listbox that contains 2 half
Next
'check if number of items its even or odd, if odd, deletes the first item of the list2,
'because its the same as the last item from list1
If eo = False Then
list2.Items.Remove(list2.Items.Item(0))
End If
End Sub

Well there are many ways to split the list. The following would distribute them evenly one by one
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
For i = 0 To ListBox1.Items.Count - 1
Dim lstbx As ListBox = If(i Mod 2 = 0, list1, list2)
lstbx.Items.Add(ListBox1.Items.Item(i))
Next
End Sub
An approach with a result more like yours would be this (requires importing System.Linq).
Note that I first set size2 to the half of the count so that it will have the extra item in case the number of items is odd.
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim size2 as Integer = ListBox1.Items.Count / 2
Dim size1 as Integer = ListBox1.Items.Count - size2
list1.Items.AddRange(ListBox1.Items.GetRange(0, size1))
list2.Items.AddRange(ListBox1.Items.GetRange(size1, size2))
End Sub

Related

Visual Studio 2017 Global Declaration

Here I want to generate a number (n) of random number into a listbox and then using another listbox to show the generated random number in accending order.
Since it is separated into two private class, i tried to use public shared for my array mark() but it doesn't seems to work.
This is my complete code.
I have no issue generating the random number into my array mark() as i declared it in the private sub.
But when I do the sorting using another button, it shows error that I did not declare my array. If I re-declare my array, the number that i stored in it will be gone and the sorting turns into all 0.
Any idea how?
Public Class Form1
Dim n As Integer
Public Shared mark() As Integer
Dim i As Integer
Dim temp As Integer
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim i As Integer
n = Val(TextBox2.Text)
TextBox2.Text = ""
ListBox1.Items.Clear()
i = 0
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
ListBox1.Items.Clear()
Dim mark(n - 1) As Integer
For i = 0 To n - 1
mark(i) = Format("#", Rnd() * 100)
ListBox1.Items.Add(mark(i))
Next
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
ListBox2.Items.Clear()
For i = 0 To n - 1
For j = 0 To n - 2
If mark(j) > mark(j + 1) Then
temp = mark(j)
mark(j) = mark(j + 1)
mark(j + 1) = temp
End If
Next
Next
For k = 0 To n - 1
ListBox2.Items.Add(mark(k))
Next
End Sub
End Class

Adding Multiple PictureBoxes To Array

So I have a total of 55 PictureBoxes that I am trying to add to an array. The naming of them looks like the Following:
Row1_Brick1, Row1_Brick2, up to Row1_Brick10
There is a total of 10 rows and there is 1 less brick in each row.
This is what I have thought of so far to make this work:
Dim bricks(0 To 54) As PictureBox 'Total of 55 Bricks Spread Out
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'Start of Loading 55 Bricks into the bricks() Array
For i = 0 To 54
For a = 1 To 10
For am = 10 To 1 Step -1
bricks(i) = ("Row" & a & "_Brick" & am)
Next
Next
Next
End Sub
Any ideas on how to do this would be great.
I recommend a jagged array, which would look like this (note that this is 0-indexed rather than 1-indexed, as with your control names):
Dim bricks(10)() As PictureBox
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'Set up child arrays
For i As Integer = 0 To 9
bricks(i) = New PictureBox(9-i)
'Set up each element in the array
For j As Integer = 0 To 9 - i
bricks(i)(j) = Me.Controls("Row" & i + 1 & "_Brick" & j + 1)
Next j
Next
End Sub
But if you really only want a single array, it is at least easier to set up (you might be able to get it down to a single line):
Dim bricks() As PictureBox
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
bricks = Me.Controls.OfType(Of PictureBox)().ToArray()
End Sub
If you need to, you can put in a Where() call to limit to pictureboxes where the name matches your patter, though it would be better to put these controls into a common Panel or GroupBox you can use as the parent rather than the form. You can also use an Orderby() call to make sure the PictureBoxes are returned in the proper sequence:
Dim bricks() As PictureBox
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
bricks = BrickPanel.Controls.
OfType(Of PictureBox)().
OrderBy(Function(pb) pb.Name). 'Naive OrderBy... 10 is before 2. I leave it to the OP to fix that part
ToArray()
End Sub
If you are unconformtalbe with the Linq functions, the trick is to increment your result array index as part of your inner loop, rather than having a separate loop by itself:
Dim bricks(54) As PictureBox
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim i As Integer = 0
For r As Integer = 1 To 10
For c As Integer = 1 to 11 - r
bricks(i) = Me.Controls("Row" & r & "_Brick" & c)
i+=1
Next c
Next r
End Sub
This is completely untested, because I was too lazy to create a new project and set up a form the same way you have, but it should be close.
Dim arr(54) As PictureBox
Dim index As Integer = 0
For row As Integer = 1 To 10
For col As Integer = 1 To 10 - row + 1 'Max column is based on the inverted value of the current row
arr(index) = Ctype(f.Controls("Row" & row & "_Brick" & col), PictureBox)
index += 1
Next
Next
This method of getting the control by the name explicitly will avoid any errors due to the order that the controls were added to the form.

VB.net datagridview to chart control devexpress

I have a study about passing DataGridView values to DevExpress ChartControl. I have X and Y values in my DataGridView (It can have different row count). I would like to use for next loop due to different point counts (needs to stop after last value). Sometimes I have 5 values, sometimes 8, 12, ... etc. I have use code below:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
For i = 0 To DataGridView1.Rows.Count - 1
ChartControl1.Series("Series 1").Points.Add(New SeriesPoint(DataGridView1.Item(0, i).Value, DataGridView1.Item(1, i).Value))
Next
End Sub
See also picture:
There is the new row in your DataGridView. You need to check for new row before adding the values from current row to your chart. To do this you can use the DataGridView.NewRowIndex property.
Here is example:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
For i = 0 To DataGridView1.Rows.Count - 1
If i <> DataGridView1.NewRowIndex Then
ChartControl1.Series("Series 1").Points.Add(New SeriesPoint(DataGridView1.Item(0, i).Value, DataGridView1.Item(1, i).Value))
End If
Next
End Sub

Iterating DataGridView gets only the values of the first two columns

I have a DataGridView that has got 5 columns. I am using a For Next loop to iterate each column's value, but for some reason it only works for column 1 and 2.
Here is my code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim a As Decimal
Dim b As Decimal
Dim i As Integer
a = 5.23
For i = 0 To DataGridView1.Rows.Count - 1
b = a * (DataGridView1.Item(i, 0).Value)
MessageBox.Show(b)
Next
End Sub
If you want to iterate each column of the first row then you need to loop up to DataGridView.Columns.Count - 1 instead.
For i = 0 To DataGridView1.Columns.Count - 1

How i can retrive the data from datagridview row click to corresponding data to another form

i am trying to retrieve data from one form to another form , on gridview click event. I have small code I got it from google search but its giving me error. in this code I was trying to retrieve it to second form datagrid. please check my code. where I am wrong.
Private Sub ReceiveGoods_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For j As Integer = 0 To frmGoodsReceive.dgvPODetails.RowCount - 1
If frmGoodsReceive.dgvPODetails.Rows(j).Cells(0).Value = True Then
Dim count As Integer = 0
For i As Integer = 0 To frmGoodsReceive.dgvPODetails.ColumnCount - 1
Me.dgvReceiveGoods.Rows(count).Cells(i).Value = frmGoodsReceive.dgvPODetails.Rows(j).Cells(i).Value
Next
count += count
End If
Next
End Sub
I am getting this error, while I run.
Conversion from string "PO003" to type 'Boolean' is not valid.
please help me
what I have the code that totally wrong code I guess. because what I am trying to do is , I have one gridview, and some data on that, when I click the row on datagrid , I want to open the corresponding information to second form gridview. this is the right way to do that?
Try Adding...
Me.dgvReceiveGoods.Rows(count).Cells(i).Value = frmGoodsReceive.dgvPODetails.Rows(j).Cells(i).Value.ToString
Ohhh okay i get it remove the if statement to transfer all your data into the form:
Private Sub ReceiveGoods_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For j As Integer = 0 To frmGoodsReceive.dgvPODetails.RowCount - 1
Dim count As Integer = 0
For i As Integer = 0 To frmGoodsReceive.dgvPODetails.ColumnCount - 1
Me.dgvReceiveGoods.Rows(count).Cells(i).Value = frmGoodsReceive.dgvPODetails.Rows(j).Cells(i).Value
Next
count += count
Next
End Sub
Or replace the if condition if you want to get all data without NULL value or Nothing
Private Sub ReceiveGoods_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For j As Integer = 0 To frmGoodsReceive.dgvPODetails.RowCount - 1
If frmGoodsReceive.dgvPODetails.Rows(j).Cells(0).Value.ToString <> "" Then
Dim count As Integer = 0
For i As Integer = 0 To frmGoodsReceive.dgvPODetails.ColumnCount - 1
Me.dgvReceiveGoods.Rows(count).Cells(i).Value = frmGoodsReceive.dgvPODetails.Rows(j).Cells(i).Value
Next
count += count
End If
Next
End Sub
Check if both DataGridView Has The Same Column if not the error may Occur ex. if your passing 10 datas vs 20 datas on other datagridview, the first datagridview will be insufficient to give required data needed by the second datagridview.
Try to analyze this one...
Solution1: DataGridView1 > DataGridview 2
Use this Code
Private Sub ReceiveGoods_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For j As Integer = 0 To frmGoodsReceive.dgvPODetails.RowCount - 1
Dim count As Integer = 0
For i As Integer = 0 To frmGoodsReceive.dgvPODetails.ColumnCount - 1
Me.dgvReceiveGoods.Rows(count).Cells(i).Value = frmGoodsReceive.dgvPODetails.Rows(j).Cells(i).Value
Next
count += count
Next
End Sub
Solution2:DataGridview1 < DataGridview2
Use this Code
Private Sub ReceiveGoods_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For j As Integer = 0 To Me.dgvReceiveGoods.RowCount -1
If frmGoodsReceive.dgvPODetails.Rows(j).Cells(0).Value.ToString <> "" Then
Dim count As Integer = 0
For i As Integer = 0 To frmGoodsReceive.dgvPODetails.ColumnCount - 1
Me.dgvReceiveGoods.Rows(count).Cells(i).Value = frmGoodsReceive.dgvPODetails.Rows(j).Cells(i).Value
Next
count += count
End If
Next
End Sub
Solution3:DataGridView1 = DataGridView 2
you can use Both...