How to show dgv2 right beneath the row in dgv1 being edited - vb.net

I am trying to show a dgv2 on dgv1 but right under the row in dgv1 being edited.
I tried with this code
Private Sub Purchases_CellBeginEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles Purchases.CellBeginEdit
Dim Y as integer = 0
For i As Integer = 0 To dgv1.CurrentRow.Index
If dgv1.Rows(i).Index < dgv1.CurrentRow.Index Then
Y = dgv1.Rows.Count * dgv1.Rows(0).Height + dgv1.ColumnHeadersHeight + 12
End If
Next
dgv2.Location = New Point(53, Y)
End Sub
I shows alright but when i go back to row 1 on dgv1, it stays where it is. Lets say i start to edit from row 1 and i get to row 4, and i want to make a correction in row 1, i want dgv2 to move back under row1.
Any help would be greatly appreciated.

Just ran into this myself and found using the mouse y position (minus top of the form + 24) worked perfect.
Private Sub DataGridView1_CellEnter(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEnter
mouseY = Windows.Forms.Cursor.Position.Y - Me.Top + 24
End Sub

I removed the if condition and it works perfectly
this is the code
Try
For i As Integer = 0 To Purchases.CurrentRow.Index
Y = i * Purchases.Rows(0).Height + Purchases.ColumnHeadersHeight + 34
Next
itemlist.Location = New Point(53, Y)
Catch ex As Exception
MsgBox(ex.Message)
End Try

Related

Progress bar gets stuck at 100%

I've programmed a "Please wait" form in which I inserted a progress bar. I looked around how to program a progress bar and this is what I did. First of all I programmed the button - Button3_Click - I press to start. Then I programmed the timer - Timer1_Tick -and so I wrote:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Timer1.Enabled = True
Timer1.Interval = 50
Timer1.Start()
*[calculus code]*
If Form18.ProgressBar1.Value = 100 Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
iProgressBarValue += 1
Select Case iProgressBarValue
Case 1, 3, 5, 7, 9
Form18.ProgressBar1.ForeColor = Color.White
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 2, 4, 6, 8
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 10
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Timer1.Stop()
Timer1.Enabled = False
End Select
End Sub
I can't understand why the progress bar gets stuck at 100% and neither form18 gets hidden, nor hrrspkexcel becomes visible. Where am I doing wrong? Thanks for any support. Best regards.
Edit: I tried to edit my code as comments say:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Timer1.Enabled = True
Timer1.Interval = 50
Timer1.Start()
[calculus code]
iProgressBarValue += 1
Select Case iProgressBarValue
Case 1, 3, 5, 7, 9
Form18.ProgressBar1.ForeColor = Color.White
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 2, 4, 6, 8
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 10
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Timer1.Stop()
Timer1.Enabled = False
End Select
If Form18.ProgressBar1.Value = 100 Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If Form18.ProgressBar1.Value = 100 Then
Timer1.Stop()
Timer1.Enabled = False
End If
End Sub
In this case, progress bar gets stuck at 10%.
Edit II: Following suggestions in comment, I removed the timer and based my progress bar on the entity of the calculus code (Form18.ProgressBar1.Maximum). Anyway, what is reported under [calculus code] is an heavy Excel export so the progress bar freezes to 0% until exportation has ended and then start running (I set loading cursor to understand when exportation has ended), so maybe I'd need of a BackgroundWorker to make my bar progressing while exporting? (I'm a beginner programmer and I read somewhere something about this, but I don't know if this solution is suitable for me, so I'm asking).
At last, this is how I corrected my code:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Form18.ProgressBar1.Minimum = 0
Form18.ProgressBar1.Value = 0
Form18.ProgressBar1.Maximum = [if loop criteria based on my code]
Form18.ProgressBar1.Increment(1)
Form18.Show()
[calculus code - excel export]
If Form18.ProgressBar1.Value = Form18.ProgressBar1.Maximum Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
End Sub
With this edit, my ProgressBar freezes at 0% even if exportation has already ended, so I'm obviously doing wrong somewhere. Thanks for all the support you're giving to me.
Edit III: I managed in making progressbar working using a for loop to increment its value, as you suggested me, with a proportional equation to percentage and to overcome the problem about the maximum value of the bar, that's always set on 100. So thanks all of you for your support. The last thing I want to ask you - if I'm not offtopic - is how to make my loading form - with the progressbar - on foreground and to "lock" interaction with all other forms.
Edit III BIS: I've tried to use Backgroundworker in order to overcome the loading-form freezing. This is the first time I'm using this command and I don't know if it's the right way to make it comunicating to a ShowDialog Form. This is what I wrote:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Form18.ProgressBar1.Minimum = 0
Form18.ProgressBar1.Value = 0
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Form18.ShowDialog()
[excel calculus export]
If Form18.ProgressBar1.Value = Form18.ProgressBar1.Maximum Then
Form18.Hide()
hrrnativexcel.Visible = True
End If
End Sub
I'm always getting the same trouble: when Form18 appears, remains on 0% loading.
Edit IV: I'm having an issue about progressbar increment for the following situation: I have two for loops for exporting values in excel and the upper bound of this loops are different. So I've created a third for loop, whose upper bound is the sum of the upper bounds of the two abovementioned for loops, in order to increment the progressbar progress. When it reaches 100%, it starts again going in loop. How could I solve this issue? Here is the code I'm using:
For i = 1 To CInt(Form6.ListBox1.Items.Count)
For j = 1 To CInt(Form10.ListBox1.Items.Count)
For k = 0 To CInt(CInt(Form6.ListBox1.Items.Count) + CInt(Form10.ListBox1.Items.Count))
hrrspkexcel.Cells(j + 1, 1).value = Form10.ListBox2.Items(CInt(j + 1) - 2)
hrrspkexcel.Cells(i + 1, 2).value = Form6.ListBox1.Items(CInt(i + 1) - 2)
Form18.ProgressBar1.Value = CInt(100 * k / (CInt(Form6.Label9.Text) + CInt(Form10.ListBox1.Items.Count)))
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Next
Next
Next
Thanks in advance.
Edit V: I've updated my code following comments in order to solve the issue described in Edit IV. This is what I wrote:
Dim pbloop As Integer
pbloop = CInt(Form10.ListBox1.Items.Count) * CInt(Form6.ListBox1.Items.Count)
For p = 1 To pbloop
For i = 1 To CInt(Form6.ListBox1.Items.Count)
For j = 1 To CInt(Form10.ListBox1.Items.Count)
hrrspkexcel.Cells(i + 1, 4).value = Form6.ListBox1.Items(CInt(i + 1) - 2)
hrrspkexcel.Cells(i + 1, 3).value = Form6.ListBox2.Items(CInt(i + 1) - 2)
hrrspkexcel.Cells(j + 1, 1).value = Form10.ListBox1.Items(CInt(j + 1) - 2)
hrrspkexcel.Cells(j + 1, 2).value = Form10.ListBox2.Items(CInt(j + 1) - 2)
Form18.ProgressBar1.Value = CInt(100 * p / pbloop)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Next
Next
I'm getting stuck always at 0% and progress bar that doesn't increase.
This is not the true answer of the problem but a sample to show you how to use a progress bar.
This code is not beautiful, I know, it's for the example. Please be careful when you use a textbox text as a number without check what is written.
Imports System.Threading
Public Class Form1
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
' Initialisation of the progressbar
myProgressbar.Value = 0
myProgressbar.Maximum = tbxTo.Text
lbxInfos.Items.Clear() ' Clear the content in the listbox1 if it's not the first run
' This simulate your [calculus code], I just add an information in the listbox
For i As Integer = tbxFrom.Text To tbxTo.Text
myProgressbar.Value = i ' Set the progressbar avancement
lbxInfos.Items.Add("This is the loop n° " & i & " !")
lbxInfos.Refresh() ' Just because the listbox will not be refresh until the end of the sub
Thread.Sleep(200) ' The code is too fast, I add this to see the progress (= wait 200 ms)
Next
MsgBox("This is the end ! Now the form will be closed")
Me.Close()
End Sub
End Class
Try something more like this out:
Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Button3.Enabled = False
hrrspkexcel.Visible = False ' changed this to a Label next to the button just for demonstration
Dim f18 As New Form18
f18.ProgressBar1.Minimum = 0
f18.ProgressBar1.Value = 0
f18.ProgressBar1.Maximum = 100 ' <-- leave the maximum at 100!
f18.Show(Me)
Dim pct As Integer
Dim maximum As Integer = 319 ' <-- figure out the max value based on your "calculus code"
Await Task.Run(Sub()
' [calculus code - excel export]
For i As Integer = 0 To maximum
System.Threading.Thread.Sleep(50) ' <- some kind of processing going on
' calculate the percentage based on your loop value "i" and the "maximum":
pct = CDbl(i) / CDbl(maximum) * 100 ' <-- scale your loop value to 100
Try
f18.ProgressBar1.Invoke(Sub()
f18.ProgressBar1.Value = pct
End Sub)
Catch ex As Exception
' User closed the progressform, create another one
Me.Invoke(Sub()
f18 = New Form18
f18.ProgressBar1.Minimum = 0
f18.ProgressBar1.Value = 0
f18.ProgressBar1.Maximum = 100 ' <-- leave it at 100
f18.Show(Me)
' make progressbar immediately jump to the right spot
f18.ProgressBar1.Value = f18.ProgressBar1.Maximum
f18.ProgressBar1.Value = pct
End Sub)
End Try
Next
End Sub)
' when we hit here, the "calculus code" above completed
f18.Close()
hrrspkexcel.Visible = True ' changed this to a Label next to the button just for demonstration
Button3.Enabled = True
End Sub
Here's what it looks like in action:
You current code reads as if you want the Progress Bar to update on a button click a maximum of 10 times before hiding the form. Is that your intention? I would have expected that you want the "Please wait ..." form to stay visible with the progress bar updating every, say, second, then disappear?
Using a timer for the latter is fine but for the former, you can simply update the progress bar directly - as you are doing - without a timer.
Also, you don't need to multiply your progress bar value by 10; you can simply set the progress bar Maximum value to 10.
Also, since you change the ForeColor value on the first click, you can probably dispense with the Case Select {even|odd} test because the code is otherwise identical.
So without the timer or the color change and with Progress Bar Maximum = 10, all you need to do is:
Form18.ProgressBar1.Value = iProgressBarValue
Form18.Label3.Text = $"{iProgressBarValue} %")
No need for the Case Select.
Another option for the PB is to use the PerformStep() method to increment it. Just set the Step property to 1 for this approach.

Nested timers? Trouble with logic on multiple simultaneous timer ticks

I'm trying to create a simple visual example and the first step is having a column of boxes (panels) move across the screen. So far I've accomplished that, but I'm also attempting to have each panel blink a few times, individually, while moving. The effect should be a type of 'round robin' loop where the first panel blinks a few times, then the second, then the third, etc, etc and repeat.
I'm quite new to VB and so far I've only been able to successfully make either only one panel blink or all of the panels blink, not each one individually. Here's my code so far:
Public Class Form1
Public ticks As Integer
Public p(4) As Panel
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
p(0) = Panel1
p(1) = Panel2
p(2) = Panel3
p(3) = Panel4
p(4) = Panel5
ticks = 0
End Sub
Private Sub tmr1_Tick(sender As Object, e As System.EventArgs) Handles tmr1.Tick
Dim i As Integer
If ticks = 1 Then
For i = 0 To 4
Dim randomValue = Rnd()
p(i).Top = 50 + 75 * i
p(i).Left = randomValue * 120
Next
ElseIf ticks > 30 Then
ticks = 0
Else
For i = 0 To 4
p(i).Left += 20
Next
End If
ticks += 1
End Sub
Private Sub tmr2_Tick(sender As System.Object, e As System.EventArgs) Handles tmr2.Tick
Dim i As Integer
For i = 0 To 4 'all of the panels blink at the same time..
If p(i).Visible = False Then
p(i).Visible = True
ElseIf p(i).Visible = True Then
p(i).Visible = False
End If
Next
End Sub
End Class
As of right now, all of the panels blink while moving across the screen in random locations, I'm assuming this is because the for loop responsible for the blinking is nested within the ticking timer, so for each tick it runs through the loop fully.
I'm a little stumped on what should be some very simple logic, but please bear with me as I am a novice.
Thank you for any and all help!
If I understand what you want, this would do it. They all blink now because they are all in the loop that occurs with each tick, this example changes each one by it's index in the array, and the index variable must be class level to retain it's value between ticks.
Private index As Integer
Private Sub tmr2_Tick(sender As System.Object, e As System.EventArgs) Handles tmr2.Tick
p(index).Visible = Not p(index).Visible
If index = 4 Then
index = 0
Else
index += 1
End If
End Sub

Change the datagridview colour based on date

i got a datagridview which displays data from database(MS Access)
the datagridview display the data correctly..
now i want to change the colour of the dgvReminder's row to yellow if current date is less than 2 days to the Date_Of_Pickup.
Date_Of_Pickup is in this format = 19-Dec-2013
So far i have test this code :-
Private Sub Home_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i As Integer = 0 To dgvReminder.Rows.Count - 1
If dgvReminder.Rows(i).Cells("Quantity").Value < 2 Then
dgvReminder.Rows(i).Cells(2).Style.BackColor = Color.Yellow
End If
Next
End Sub
The whole Quantity column which has value less than 2 turn to yellow
but how can i do this with the Date_Of_Pickup column??
try something like this:
If DateDiff(DateInterval.Day,dgvReminder.Rows(i).Cells("Date_Of_Pickup").Value,Now()) > 2) Then
dgvReminder.Rows(i).Cells(2).Style.BackColor = Color.Yellow
End If
I did this one and it works , I just checked if the record is expired or about to expire within ongoing month. you can just change the date interval as your need. I used DataBinding Complete event of Data GridView
Private Sub grdMembersInfo_DataBindingComplete(sender As System.Object, e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles grdMembersInfo.DataBindingComplete
For i = 0 To grdMembersInfo.Rows.Count - 1
Dim expDate As Date = grdMembersInfo.Rows(i).Cells("iCardExpiryDate").Value
If DateDiff(DateInterval.Month, Date.Now, expDate) <= 0 Then
grdMembersInfo.Rows(i).DefaultCellStyle.BackColor = Color.LightPink
Else
grdMembersInfo.Rows(i).DefaultCellStyle.BackColor = Color.LightGreen
End If
Next
End Sub

VB.NET: How to add more than one control to WinForm programmatically

I'm trying to add labels to my form on the timer tick event. It adds the first label no problem, but doesn't seem to add any more.
After some debugging I can see that the controls are added but it only ever displays the first label. Is there something I'm missing here?
Private Sub timTick1_Tick(sender As System.Object, e As System.EventArgs) Handles timTick1.Tick
iTick1 += 1
lblTick1.Text = iTick1
iPhase += 1
lblPhase.Text = iPhase
Select Case iPhase
Case 1
Phase1()
Case 2
Phase2()
Case 3
Phase3()
Case 4
Phase4()
End Select
If iPhase = 4 Then
iPhase = 0
End If
End Sub
Private Sub Phase4()
Panel3.Controls.Add(New Label With {.Text = "TESTING" & iTick1, .Location = New Point(iTick1, iTick1)})
End Sub

Programmatically change selection on DatagridView (.NET)

I'm learning VB.NET.
I've a problem with DataGridView component when trying to set the value of the CurrentCell.
What i'm trying to do is :
I've a DataGridView With values.
I want to make a button in my forms and when clicking on it I want to change the selection from the current row to the next. To explain more, by clicking my Button I want to simulate the effect of a mouse click on a DataGridview.
I hope you can help me,
Thanks!
Maybe something like this:
If DataGridView1.RowCount > 0 Then
Dim MyDesiredIndex As Integer = 0
If DataGridView1.CurrentRow.Index < DataGridView1.RowCount - 1 Then
MyDesiredIndex = DataGridView1.CurrentRow.Index + 1
End If
DataGridView1.ClearSelection()
DataGridView1.CurrentCell = DataGridView1.Rows(MyDesiredIndex).Cells(0)
DataGridView1.Rows(MyDesiredIndex).Selected = True
End If
Note 1: maybe these two lines are not necessary. I haven´t proved it
DataGridView1.ClearSelection()
DataGridView1.CurrentCell = DataGridView1.Rows(MyDesiredIndex).Cells(0)
Note 2: note that if we are in the last row, it goes to first
You need to set the particular row's Selected property to true. I think the VB would be something like this:
someDGV.Rows(index).Selected = True
If your data grid is bound to a BindingSource, it is better to change the position there:
Object key = Convert.ToInt32(cdr["WordList"]);
int itemFound = lexiconNamesBindingSource.Find("ID_Name", key);
lexiconNamesBindingSource.Position = itemFound;
...and you might need to finish it off with:
lexiconNamesBindingSource.ResetBidings();
(This is an old thread, but I found it, so someone else might find this useful)
Just use the BindingSource.MoveNext() and BindingSource.MovePrevious() methods.
You could do it this way:
If DataGridView1.CurrentRow.Index < DataGridView1.Rows.Count Then
DataGridView1.Rows(DataGridView1.CurrentRow.Index + 1).Selected = True
End If
To get the selected row, you should use SelectedRows(0).Index inspite of CurrentRow. Because if you programmaticaly make a row as selected, then next time you will find 0 in CurrentRow.Index. So It would be like :
If DataGridView1.SelectedRows(0).Index < DataGridView1.RowCount - 1 Then
MyDesiredIndex = DataGridView1.SelectedRows(0).Index + 1
End If
DataGridView1.Rows(MyDesiredIndex).Selected = True
expanding on the answer above which is perfect considering I spent at least 4 hours loooking for this.
and assuming that your datagridview is called dgvDevices... this code will handle the event in which you go outbounce as you move back and forward on your rows
Private Sub btnPrev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrev.Click
Try
dgvDevices.ClearSelection()
Dim currentr As Integer = dgvDevices.CurrentCell.RowIndex
dgvDevices.CurrentCell = dgvDevices.Rows(currentr - 1).Cells(0)
dgvDevices.Rows(currentr - 1).Selected = True
Catch ex As Exception
dgvDevices.CurrentCell = dgvDevices.Rows(0).Cells(0)
dgvDevices.Rows(0).Selected = True
End Try
End Sub
Private Sub btnForw_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnForw.Click
Try
dgvDevices.ClearSelection()
Dim currentr As Integer = dgvDevices.CurrentCell.RowIndex
dgvDevices.CurrentCell = dgvDevices.Rows(currentr + 1).Cells(0)
dgvDevices.Rows(currentr + 1).Selected = True
Catch ex As Exception
dgvDevices.CurrentCell = dgvDevices.Rows(dgvDevices.RowCount - 1).Cells(0)
dgvDevices.Rows(dgvDevices.RowCount - 1).Selected = True
End Try
End Sub
Besides Javiers correct answer, if you're using BindingSource for your datagridview then it will be better to change selected item from binding source rather than using datagridview.CurrentCell:
' Example Definitions
Dim bsExample As New BindingSource
Dim dgv As New DataGridView
dgv.DataSource = bsExample
' Example code to change current row position
Dim desiredIndex As Integer = 10
bsExample.Position = desiredIndex
Private Sub DGW2_DataBindingComplete(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles DGW2.DataBindingComplete
Dim mygrid As DataGridView
mygrid = CType(sender, DataGridView)
mygrid.ClearSelection()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If DataGridView1.Rows.Count - 1 > 0 Then
For i As Integer = 0 To DataGridView1.Rows.Count - 1 Step +1
If DataGridView1.Rows.Count - 1 > 0 Then
DataGridView1.Rows.RemoveAt(0)
End If
Next
Else
End If
End Sub
Easy with Extensions
Imports System.Runtime.CompilerServices
Module Extensions
''' <summary>
''' Select the Row(Index)
''' </summary>
''' <param name="Dgv">The DataGridView</param>
''' <param name="Index">The Row Index (0 First)</param>
''' <param name="ScroolToTop">If True scrool the row to top</param>
''' <returns>True if no error or False if something went wrong</returns>
' USE: if not DataGridView1.GoToRow(30) then MsgBox("Something went wrong!)
<Extension()>
Public Function GoToRow(Dgv As DataGridView, Index As Integer, Optional ScroolToTop As Boolean = True) As Boolean
If Index > -1 And Index < Dgv.Rows.Count - 1 Then
With Dgv
.ClearSelection()
.Rows(Index).Selected = True
If ScroolToTop Then .FirstDisplayedScrollingRowIndex = Index
End With
Return True
End If
Return False
End Function
End Module
I have DataGridView like that :
| ID | Name |
|:---|:-----:|
| 1 | Samir |
I search by 'Name' using this code :
Private Sub GunaButton6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GunaButton6.Click
Dim temp As Integer = 0
For i As Integer = 0 To Me.Listofclient.RowCount - 2
If Me.Listofclient.Rows(i).Cells(1).Value.ToString = EDSearch.Text Then
Me.Listofclient.ClearSelection()
Me.Listofclient.Rows(i).Selected = True
temp = 1
End If
Next
If temp = 0 Then
MsgBox("Item not found")
End If
End Sub