VB - Issues With Progress Bar - vb.net

I'm making a simple progress bar to be used as a splash screen within my application but when the code is executed, the loading bar does not reach the end of the progress bar.
I've used the code:
splashprogressbar.Increment(1)
If splashprogressbar.Value = 100 Then
Main_Menu.Show()
Me.Hide()
End If
to open a form when the progress bar reaches 100, which has been set as the maximum value.
The issue is more so related to appearance rather than functionality but i would still like to understand why this occurs and hopefully get a fix.
To clarify, the form Main_Menu, opens when the bar is about 3/4 of the way completed and i can't get my head around why this occurs. Any ideas?

I couldn't imagine that VB has such a bug. Probably you are running an old or incompatible ".Net Framework" that causes that.
You can try to set your Progressbars maximum programatically while running the program.
Use this code in the Form1_Load event:
ProgressBar1.Maximum = 100
It should work. But if it doesn't, maybe it's just code related. Try to fill your progressbar this way (It must be in a timer):
If splashprogressbar.Value = splashprogressbar.Maximum Then
Main_Menu.Show()
Me.Hide()
Else
splashprogressbar.Value += 100
End If
Just a friendly advice: It seems you're simulating a fake loading bar which fills and then, only then, open the app (Potentially wasting the users time). Don't do that.

You could also try taking a look at the following link. This may help with your approach;
Trigger Background Worker
The below was copied from the link above...
Dim WithEvents bgWorker As New BackgroundWorker With { _
.WorkerReportsProgress = True, _
.WorkerSupportsCancellation = True}
Private Sub bgWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgWorker.DoWork
For i As Integer = 0 To 100
'Threw in the thread.sleep to illustrate what's going on. Otherwise, it happens too fast.
Threading.Thread.Sleep(250)
bgWorker.ReportProgress(i)
Next
End Sub
Private Sub bgWorker_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgWorker.ProgressChanged
If e.ProgressPercentage Mod 10 = 0 Then
MsgBox(e.ProgressPercentage.ToString)
End If
End Sub
Private Sub bgWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgWorker.RunWorkerCompleted
MsgBox("Done")
End Sub

you could try something like this;
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.Show()
Dim i As Integer
splashprogressbar.Minimum = 0
splashprogressbar.Maximum = 100
If splashprogressbar.Value < splashprogressbar.Maximum Then
For i = 0 To 100
splashprogressbar.Value = i
Application.DoEvents()
System.Threading.Thread.Sleep(100)
Next
End If
Me.Hide()
MsgBox("Here I am") 'Use your "Main_Menu.Show" here
End Sub

Related

Visual Basic Custom Progress Bar Not Moving

I am a beginner in VB, and I tried making a progress bar from two panels, but the front one isn't moving. Code:
Public Class Startup
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If Front.Width < Me.Width Then
Front.Width = Front.Width + 10
End If
If Front.Width = "1366" Then
Timer1.Stop()
Login.Show()
Me.Close()
End If
End Sub
What INDEX said is absolutely correct!
You should be testing against a number not a string
If Front.Width = 1366 Then
Then note his/her second point!
You are incrementing in steps of 10, you will pass by 1366 without hitting it!
Therefore your should change the IF statement to
If Front.Width >= 1366 Then

Looping backgroundworker

I have a vb.net application that I want to be made a) visible and b) topmost when the activewindow is set to my requirements - this part I have covered off fine.
What I want to be able to do is to use the backgroundworker to actively monitor this on a continuous loop - again I have covered this off fine.
The problem I am having is that when I am selecting a combobox, I cannot make a selection due to interference from the bgw - almost like when I click on the combobox to show the list, the bgw seems to almost do a click away from the combobox closing the list.
Any help would greatly be appreciated.
Here is my code:
Private Delegate Sub progressDelegate()
Private Sub frmApp_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.bgwActiveWindow.RunWorkerAsync()
End Sub
Private Sub bgwActiveWindow_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwActiveWindow.DoWork
Dim CheckWindow As progressDelegate
CheckWindow = New progressDelegate(AddressOf SetAppTopMost)
Me.Invoke(CheckWindow)
System.Threading.Thread.Sleep(100)
End Sub
Private Sub SetAppTopMost()
Dim bol As Boolean
If getActiveWindowTitle.IndexOf("Microsoft Outlook") <> -1 Or _
getActiveWindowTitle.IndexOf(My.Settings.AppName) <> -1 Then
bol = True
Else
bol = False
End If
Me.Visible = bol
Me.TopMost = bol
End Sub
Private Sub bgwActiveWindow_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgwActiveWindow.RunWorkerCompleted
bgwActiveWindow.RunWorkerAsync()
End Sub
as Praveen mentioned, check the state before setting it, to prevent setting focus to the window again. also, don't recreate the backworker thread each time:
Imports System.ComponentModel
Private Sub bgwActiveWindow_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bgwActiveWindow.DoWork
Do
' backworker code
Threading.Thread.Sleep(1000)
Loop While True
End Sub
of course, you'll either have to implement the 'supportscancellation' junk, or simple set a flag in your main thread and poll that on each loop and exit/break if you want to cancel.
you could also use a timer, which won't lock the thread.
i think you should add an additional check in your SetAppTopMost sub.
if Me.Visible = True then exit sub
This line should be 1st line. Since you are trying to show the form every 100ms, you are loosing focus.

Delaying in VB.net

my issue is i need to wait 3-4 seconds after a button has been pressed before i can check for it, here is my code under button1_click:
While Not File.Exists(LastCap)
Application.DoEvents()
MsgBox("testtestetstets")
End While
PictureBox1.Load(LastCap)
I think i'm doing something really simple wrong, i'm not the best at VB as i'm just learning so any explaining would be great!
~Thanks
If the reason you are needing to wait is for the file to be created try using a FileSystemWatcher and respond to the Created and Changed Events that way you are responding to an event rather than arbitrarily waiting a select period of time.
Something like:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
FileSystemWatcher1.Path = 'Your Path Here
FileSystemWatcher1.EnableRaisingEvents = True
'Do what you need to todo to initiate the file creation
End Sub
Private Sub FileSystemWatcher1_Created(sender As Object, e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Created, FileSystemWatcher1.Changed
If e.Name = LastCap Then
If (System.IO.File.Exists(e.FullPath)) Then
FileSystemWatcher1.EnableRaisingEvents = False
PictureBox1.Load(e.FullPath)
End If
End If
End Sub
You can use, although not recommended:
Threading.Thread.Sleep(3000) 'ms
This will wait 3 seconds, but also block everything else on the same thread. If you run this in the form your user-interface will not response until the wait is over.
just as a side note: use MessageBox.Show("My message") instead of MsgBox (latter is from old VB).
If you want your form to continue to function while the 3 seconds pass, you can add a Timer control instead, with some code like this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' set the timer
Timer1.Interval = 3000 'ms
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Timer1.Stop()
'add delayed code here
'...
'...
MessageBox.Show("Delayed message...")
End Sub
Drag and drop a Timer control from your toolbox to your form. It's not visible at runtime
or better yet making a wait function using stop watch, this wont halt the process in the same thread like thread sleep
' Loops for a specificied period of time (milliseconds)
Private Sub wait(ByVal interval As Integer)
Dim sw As New Stopwatch
sw.Start()
Do While sw.ElapsedMilliseconds < interval
' Allows UI to remain responsive
Application.DoEvents()
Loop
sw.Stop()
End Sub
usage
wait(3000)
for 3 sec delay
You could use this
Public Sub BeLazy()
For i = 1 To 30
Threading.Thread.Sleep(100)
Application.DoEvents()
Next
End Sub
It will delay for 3 seconds.

Iteration Not Working As Intended

I'm using a DO interation to loop a function I'm using to test for internet connectivity. The code is working fine, except that when one of the tests is satisfied the loop stops. I want this to continue in the background while the program is running. How can I get this to work?
Private Sub checkInternet()
Dim InetChecker As Boolean
InetChecker = CheckForInternetConnection()
Do While LabelCount.Text <> ""
Thread.Sleep(10)
If InetChecker = True Then
Dim image = My.Resources.greenbar
PictureBox4.Image = image
Else
Thread.Sleep(10)
Dim image = My.Resources.redbar
PictureBox4.Image = image
'NoInetConnError.Show()
End If
Loop
End Sub
Your assistance would be greatly appreciated, thanks.
Put a BackgroundWorker on your form (you will find it in the Components section of the Toolbox).
In the Properties window set WorkerReportsProgress to True for your BackgroundWorker.
Insert the following code to your form
Private connected As Boolean
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) _
Handles BackgroundWorker1.DoWork
While True
Dim online = CheckForInternetConnection()
If online <> connected Then
connected = online
BackgroundWorker1.ReportProgress(CInt(online))
End If
Thread.Sleep(500)
End While
End Sub
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
Handles BackgroundWorker1.ProgressChanged
Dim online As Boolean = CBool(e.ProgressPercentage)
If online Then
PictureBox4.Image = My.Resources.greenbar
Else
PictureBox4.Image = My.Resources.redbar
End If
End Sub
Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
' Start the background worker
BackgroundWorker1.RunWorkerAsync()
End Sub
Note that Sub BackgroundWorker1_DoWork runs on a separate thread and does not freeze your form while it is running.
It would be best to do something like this in a Timer and not in a loop.
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
If CheckForInternetConnection Then
PictureBox4.Image = My.Resources.greenbar
Else
PictureBox4.Image = My.Resources.redbar
End If
End Sub
If you have access to .Net framework 3+ then you could use the DispatcherTimer class which essentially creates an interval (set at whatever length you require) which you can handle the tick event for. When the tick event is raised, you can do your internet connection check.
Modifying the MSDN example for your situation, you could do something like this:
' DispatcherTimer setup
dispatcherTimer = New Threading.DispatcherTimer()
AddHandler dispatcherTimer.Tick, AddressOf dispatcherTimer_Tick
dispatcherTimer.Interval = New TimeSpan(0,0,1) ' Or however long you want
dispatcherTimer.Start()
Private Sub dispatcherTimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
' Checks to see whether an internet connection is still available etc
checkInternet()
' Forcing the CommandManager to raise the RequerySuggested event
CommandManager.InvalidateRequerySuggested()
End Sub

Drop onto FlowLayoutPanel

Hi guys Hope all is well
I am wondering(struggling) the following:
I have 5 flowLayoutPanels and 5 PictureBoxes i want to be able to move anyone of the picture boxes over anyone the FLP at run time and have the layout panel add it to FLP.controls.Add()....
I've been at it for Hours and now ill swallow my pride -
I have done the following To get it working, but here i have to manually specify which PixBox intersects with which FLP and i dont want 25 if statements
Private Sub cpbPic1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cpbPic1.MouseUp
If (flpDock1.HasChildren = False) Then 'Test to see if panel is filled
If CBool(CustomPictureBox.IntersectingObjects(cpbPic1, flpDock1)) Then
flpDock1.Controls.Add(cpbPic1) 'Add Pic to Panel
End If
End Sub
cpb: CustomPictureBox
you could always do this:
Private Sub cpbPic1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cpbPic1.MouseUp, cpbPic2.MouseUp, cpbPic3.MouseUp,cpbPic4.MouseUp,cpbPic5.MouseUp
If Not flpDock1.HasChildren Then 'Test to see if panel is filled
If CBool(CustomPictureBox.IntersectingObjects(TryCast(sender,CustomPictureBox), flpDock1)) Then
flpDock1.Controls.Add(TryCast(sender,CustomPictureBox)) 'Add Pic to Panel
End If
End Sub
This will reduce the amount of code you'll have to write significantly, you can further reduce this amount if you think about how to utilize the fact that the event handler passes the Object which raises the flag, like I did here.
Also you can use arbitrary big amount (i think) of objects in a handler as long as they raise the same event
well this can be a work around for what you want to do.
you also have to enable allowdrop to the flowpanels
Private Function FindControl(ByVal ControlName As String, ByVal CurrentControl As Control) As Control
' get the control you need
Dim ctr As Control
For Each ctr In CurrentControl.Controls
If ctr.Name = ControlName Then
Return ctr
Else
ctr = FindControl(ControlName, ctr)
If Not ctr Is Nothing Then
Return ctr
End If
End If
Next ctr
End Function
Private Sub me_DragEnter(sender As Object, e As DragEventArgs) Handles FLP1.DragEnter,FLP2.DragEnter,FLP3.DragEnter
' call the copy effect
If (e.Data.GetDataPresent(DataFormats.Text)) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Sub me_DragDrop(sender As Object, e As DragEventArgs) Handles FLP1.DragDrop,FLP2.DragDrop,FLP3.DragDrop
' get the FLp you're gonna drop the control onto
Dim c As control =FindControl(e.Data.GetData(DataFormats.Text), me)
sender.Controls.Add(c)
end sub
Private Sub Pictureboxs_MouseDown(sender As Object, e As MouseEventArgs) Handles Label1.MouseDown, PB.MouseDown
sender.DoDragDrop(sender.Name, DragDropEffects.Copy)
End Sub
hope that this helps you :) (sorry for my bad english)