ProgressBar not updating using a For Each loop - vb.net

I'm copying all the .avi and .png files from one folder into another:
Private Sub CopierSend_Button_Click(sender As Object, e As EventArgs) Handles CopierSend_Button.Click
If MessageBox.Show("Click OK to send media or just Cancel.", "Media Copier", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = DialogResult.OK Then
For Each foundFile As String In My.Computer.FileSystem.GetFiles(FrapsFolder_, Microsoft.VisualBasic.FileIO.SearchOption.SearchTopLevelOnly, "*.avi", "*.png")
Dim foundFileInfo As New System.IO.FileInfo(foundFile)
My.Computer.FileSystem.CopyFile(foundFile, DestFolder_ & foundFileInfo.Name, Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)
Next
Else
'Nothing Yet
End If
End Sub
I want to add a ProgressBar which will count every time a file is copied, so I added this code before the For Each loop:
Dim file1() As String = IO.Directory.GetFiles(FrapsFolder_, "*.avi")
Dim file2() As String = IO.Directory.GetFiles(FrapsFolder_, "*.png")
Dim files = file1.Length + file2.Length
Copier_ProgressBar.Step = 1
Copier_ProgressBar.Maximum = files
And added this code inside the For Each loop:
Copier_ProgressBar.Value += 1
Here is all of my code:
Private Sub CopierSend_Button_Click(sender As Object, e As EventArgs) Handles CopierSend_Button.Click
If MessageBox.Show("Click OK to send media or just Cancel.", "Media Copier", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = DialogResult.OK Then
Dim file1() As String = IO.Directory.GetFiles(FrapsFolder_, "*.avi")
Dim file2() As String = IO.Directory.GetFiles(FrapsFolder_, "*.png")
Dim files = file1.Length + file2.Length
Copier_ProgressBar.Step = 1
Copier_ProgressBar.Maximum = files
For Each foundFile As String In My.Computer.FileSystem.GetFiles(FrapsFolder_, Microsoft.VisualBasic.FileIO.SearchOption.SearchTopLevelOnly, "*.avi", "*.png")
Dim foundFileInfo As New System.IO.FileInfo(foundFile)
My.Computer.FileSystem.CopyFile(foundFile, DestFolder_ & foundFileInfo.Name, Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)
Copier_ProgressBar.Value += 1
Next
Else
'Nothing Yet
End If
End Sub
The ProgressBar updates, but only after all the files have been copied instead of updating in real time. Any idea?

As it stands it looks like the ProgressBar doesn't do anything until after all the files have copied. That isn't strictly true. Instead your UI is not updating.
Instead you should look into using a BackgroundWoker to report progress. Something like this should do the trick:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'This can also be set using the Designer
BackgroundWorker1.WorkerReportsProgress = True
End Sub
Private Sub CopierSend_Button_Click(sender As Object, e As EventArgs) Handles CopierSend_Button.Click
If MessageBox.Show("Click OK to send media or just Cancel.", "Media Copier", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = DialogResult.OK Then
Dim file1() As String = IO.Directory.GetFiles(FrapsFolder_, "*.avi")
Dim file2() As String = IO.Directory.GetFiles(FrapsFolder_, "*.png")
Dim files As Integer = file1.Length + file2.Length
Copier_ProgressBar.Step = 1
Copier_ProgressBar.Maximum = files
BackgroundWorker1.RunWorkerAsync()
End If
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For Each foundFile As String In My.Computer.FileSystem.GetFiles(FrapsFolder_, Microsoft.VisualBasic.FileIO.SearchOption.SearchTopLevelOnly, "*.avi", "*.png")
Dim foundFileInfo As New System.IO.FileInfo(foundFile)
My.Computer.FileSystem.CopyFile(foundFile, DestFolder_ & foundFileInfo.Name, Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)
BackgroundWorker1.ReportProgress(Copier_ProgressBar.Value + 1)
Next
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Copier_ProgressBar.Value = e.ProgressPercentage
End Sub
As an additional note, for best practice, I would consider using Path.Combine instead of concatenating strings together:
My.Computer.FileSystem.CopyFile(foundFile, Path.Combine(DestFolder_, foundFileInfo.Name), Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)

Related

Copy a File Using DragDrop VB.Net

What is wrong with my code? Getting a 'Process cannot access the file because it is being used by another process' error msg Is there a way around this. My google-fu was not giving me much luck. I was not able to Move or Copy, and I will take either.
Private Sub frmFiberTransMain_DragEnter(sender As Object, e As DragEventArgs) Handles MyBase.DragEnter
If e.Data.GetDataPresent(DataFormats.FileDrop, False) = True Then
e.Effect = DragDropEffects.All
End If
End Sub
Private Sub frmFiberTransMain_DragDrop(sender As Object, e As DragEventArgs) Handles MyBase.DragDrop
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
Dim filePaths As String() = CType(e.Data.GetData(DataFormats.FileDrop), String())
Call CopyFileDrop(filePaths)
End If
End Sub
Private Sub CopyFileDrop(filePaths As String())
For Each fileLoc As String In filePaths
Dim fileName As String = fileLoc
Dim fi As New IO.FileInfo(fileName)
File.Create(fileName)
Dim justFileName As String = fi.Name
Dim newPathName As String = gProgDir & "\" & justFileName
Directory.Move(fileLoc, newPathName)
Next fileLoc
End Sub
File.Create(fileName) returns an open handle and you're not closing it. It doesn't look like you need that line. –
#LarsTech 50 mins ago

How to remove path in my search code on vb.net

I am very new to VB and I have an assignment which requires me to have search code in the program.The search code works but it shows the path of the file and I just want it to show the name of the txt file.
Private Sub SearchOrdersToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SearchOrdersToolStripMenuItem.Click
txtSearch.Visible = True
Lblsearch.Visible = True
Dim backslash As String() = FrmLogIn.FolderDirectory.Split("\")
Dim filename As String = backslash(6)
ListOfAllFileNames = System.IO.Directory.GetFiles(FrmLogIn.FolderDirectory)
TxtShoworders.Lines = ListOfAllFileNames
End Sub
Private Sub txtSearch_TextChanged(sender As Object, e As EventArgs) Handles txtSearch.TextChanged
If txtSearch.Text = "" Then
TxtShoworders.Lines = ListOfAllFileNames
Return
Else
Dim SearchResults As New List(Of String)
For Each currentFileName In ListOfAllFileNames
If currentFileName.Contains(txtSearch.Text) Then
SearchResults.Add(currentFileName)
End If
Next
TxtShoworders.Lines = SearchResults.ToArray()
End If
End Sub
Link to what the program looks like and the directory showing
If anyone could help me with this that would be great, thanks.
You'll have to use Path.GetFileName for this, example:
SearchResults.Add(Path.GetFileName(currentFileName))
To keep your list of paths but only show the filenames, try this:
Private Sub SearchOrdersToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SearchOrdersToolStripMenuItem.Click
txtSearch.Visible = True
Lblsearch.Visible = True
Dim backslash As String() = FrmLogIn.FolderDirectory.Split("\")
Dim filename As String = backslash(6)
ListOfAllFileNames = System.IO.Directory.GetFiles(FrmLogIn.FolderDirectory)
TxtShoworders.Lines = GetFileNames(ListOfAllFileNames)
End Sub
Private Sub txtSearch_TextChanged(sender As Object, e As EventArgs) Handles txtSearch.TextChanged
If txtSearch.Text = "" Then
TxtShoworders.Lines = GetFileNames(ListOfAllFileNames)
Return
Else
Dim SearchResults As New List(Of String)
For Each currentFileName In ListOfAllFileNames
If currentFileName.Contains(txtSearch.Text) Then
SearchResults.Add(currentFileName)
End If
Next
TxtShoworders.Lines = GetFileNames(SearchResults.ToArray())
End If
End Sub
Private Function GetFileNames(Byval paths as String()) As String()
Return paths.Select(Function(p) Path.GetFileName(p)).ToArray()
End Function
This will keep your ListOfAllFileNames containing the paths while only showing the file names using GetFileNames.

Creating a Variable with StreamReader Split Results

I've recently been exposed to vb.net scripting and I am having some trouble figuring out how to accomplish a task. I'm supposed to create a program that will automate an end user process but right now it only works for one specific id(because I've hardcoded a value to make the script run). I've scripted the use of StreamReader to loop through all the possible entries, but I can't figure out how to put that result into a variable so the program will automatically read the id selected and proceed through the steps, then loop until all id's identified via StreamReader have been processed. I apologize if this has been asked before, I am not very familiar with the terminology.
Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
Application.DoEvents()
End
End Sub
Private Sub Form1_FormLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
uxNote.Text = "Starting"
Me.Update()
RunApp()
Me.Close()
End Sub
Sub RunApp()
Dim b As New BostonWorkStation
Dim myHandle As Long
b.Shell_("C:\Software\Application.exe")
b.Activate("AppCaption", True)
b.Connect("AppCaption", enumStreamType1.stWindows)
uxNote.Text = myHandle.ToString
Me.Update()
b.Wait(2)
b.Pause("#378,423")
b.Tab_("user")
b.Enter("password")
b.Wait(2)
b.Shell_("C:\Software\Application2.exe")
b.Activate("App2Caption", True)
b.Wait(4)
b.Connect("App2Caption", enumStreamType1.stWindows)
uxNote.Text = myHandle.ToString
Me.Update()
b.Wait(4)
b.Smart.Create("App2Caption#726,1088", -1024, -633, 0)
b.Smart.Click(False, False)
b.Wait(3)
b.Activate("Patient Lookup", True)
b.Connect("Patient Lookup", enumStreamType1.stWindows)
uxNote.Text = myHandle.ToString
Me.Update()
b.Wait(1)
b.Pause("#104,423")
ProcessPatients(b)
b.Enter("10001") 'hardcoded id this is where I would like a variable to pull in the value
b.Wait(2)
'some more code steps here specific to what should be done once patient id has been selected
End Sub
Sub ProcessPatients(ByVal w As BostonWorkStation)
Dim record() As String
Dim sr As New StreamReader("my path for csv or txt file")
Do While sr.Peek > -1
record = sr.ReadLine.Split(CChar("|"))
Loop
sr.Close()
End Sub
I imagine it would look something like this:
Imports System.IO
Public Class Form1
Private Sub Form1_FormLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
uxNote.Text = "Starting"
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
RunApp()
End Sub
Sub RunApp()
Dim b As New BostonWorkStation
Dim myHandle As Long
b.Shell_("C:\Software\Application.exe")
b.Activate("AppCaption", True)
b.Connect("AppCaption", enumStreamType1.stWindows)
uxNote.Text = myHandle.ToString
Me.Refresh()
Application.DoEvents()
b.Wait(2)
b.Pause("#378,423")
b.Tab_("user")
b.Enter("password")
b.Wait(2)
b.Shell_("C:\Software\Application2.exe")
b.Activate("App2Caption", True)
b.Wait(4)
b.Connect("App2Caption", enumStreamType1.stWindows)
uxNote.Text = myHandle.ToString
Me.Refresh()
Application.DoEvents()
b.Wait(4)
b.Smart.Create("App2Caption#726,1088", -1024, -633, 0)
b.Smart.Click(False, False)
b.Wait(3)
b.Activate("Patient Lookup", True)
b.Connect("Patient Lookup", enumStreamType1.stWindows)
uxNote.Text = myHandle.ToString
Me.Refresh()
Application.DoEvents()
b.Wait(1)
b.Pause("#104,423")
ProcessPatients(b)
Me.Close()
End Sub
Sub ProcessPatients(ByVal w As BostonWorkStation)
Dim ID As String
Dim record() As String
Dim sr As New StreamReader("my path for csv or txt file")
Do While Not sr.EndOfStream
record = sr.ReadLine.Split(CChar("|"))
ID = record(0) ' <-- grab your "ID" from somewhere in "record"
w.Enter(ID)
w.Wait(2)
'some more code steps here specific to what should be done once patient id has been selected
Loop
sr.Close()
End Sub
End Class

How do I get a value from a dynamic control?

I've got a form with a picturecontrol (default to black bg) and I have a flowlayoutpanel underneath. On the form's load it cycles through a folder of images and creates a thumbnail (picturecontrol) inside the flowlayoutpanel. What I want to do is dynamically add a click event to let the user change the main picturecontrol image with one of the thumbnails.
Private Sub TabImageLoad()
Dim apppath As String = Application.StartupPath()
Dim strFileSize As String = ""
Dim di As New IO.DirectoryInfo(apppath + "\images")
Dim aryFi As IO.FileInfo() = di.GetFiles("*.*")
Dim fi As IO.FileInfo
For Each fi In aryFi
If fi.Extension = ".jpg" Or fi.Extension = ".jpeg" Or fi.Extension = ".gif" Or fi.Extension = ".bmp" Then
Dim temp As New PictureBox
temp.Image = Image.FromFile(di.ToString + "\" + fi.ToString)
temp.Width = 100
temp.Height = 75
temp.Name = fi.ToString
temp.Visible = True
temp.SizeMode = PictureBoxSizeMode.StretchImage
AddHandler temp.Click, AddressOf Me.temp_click
FlowLayoutPanel1.Controls.Add(temp)
End If
Next
End Sub
Private Sub temp_click(ByVal sender As System.Object, ByVal e As System.EventArgs)
PictureBox1.Image = temp.Image
End Sub
This is my code for the sub that gets the images (note the addhandler attempt) and the sub that links to the addhandler. As you've probably guessed the addhandler doesn't work because "temp" is not declared in the temp_click sub.
Any suggestions?
The sender argument is always the control that triggered the event, in this case a PictureBox:
Private Sub temp_click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim pb As PictureBox = DirectCast(sender, PictureBox)
PictureBox1.Image = pb.Image
End Sub
I suggest you to use:
Private Sub temp_click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim pbDynamic as PictureBox = trycast(sender,Picturebox)
Then validate with
if pbDynamic IsNot Nothing Then
PictureBox1.Image = pbDynamic.image
end if
This way you avoid runtime errors and null pointer exceptions

Read Text File and Output Multiple Lines to a Textbox

I'm trying to read a text file with multiple lines and then display it in a textbox. The problem is that my program only reads one line. Can someone point out the mistake to me?
Imports System.IO
Imports Microsoft.VisualBasic.FileIO
Public Class Form1
Private BagelStreamReader As StreamReader
Private PhoneStreamWriter As StreamWriter
Dim ResponseDialogResult As DialogResult
Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
'Dim PhoneStreamWriter As New StreamWriter(OpenFileDialog1.FileName)
'Is file already open
If PhoneStreamWriter IsNot Nothing Then
PhoneStreamWriter.Close()
End If
With OpenFileDialog1
.InitialDirectory = Directory.GetCurrentDirectory
.FileName = OpenFileDialog1.FileName
.Title = "Select File"
ResponseDialogResult = .ShowDialog()
End With
'If ResponseDialogResult <> DialogResult.Cancel Then
' PhoneStreamWriter = New StreamWriter(OpenFileDialog1.FileName)
'End If
Try
BagelStreamReader = New StreamReader(OpenFileDialog1.FileName)
DisplayRecord()
Catch ex As Exception
MessageBox.Show("File not found or is invalid.", "Data Error")
End Try
End Sub
Private Sub DisplayRecord()
Do Until BagelStreamReader.Peek = -1
TextBox1.Text = BagelStreamReader.ReadLine()
Loop
'MessageBox.Show("No more records to display.", "End of File")
'End If
End Sub
Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles SaveToolStripMenuItem.Click
With SaveFileDialog1
.InitialDirectory = Directory.GetCurrentDirectory
.FileName = OpenFileDialog1.FileName
.Title = "Select File"
ResponseDialogResult = .ShowDialog()
End With
PhoneStreamWriter.WriteLine(TextBox1.Text)
With TextBox1
.Clear()
.Focus()
End With
TextBox1.Clear()
End Sub
Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
Dim PhoneStreamWriter As New StreamWriter(OpenFileDialog1.FileName)
PhoneStreamWriter.Close()
Me.Close()
End Sub
End Class
Here is a sample textfile:
Banana nut
Blueberry
Cinnamon
Egg
Plain
Poppy Seed
Pumpkin
Rye
Salt
Sesame seed
You're probably only getting the last line in the file, right? Your code sets TextBox1.Text equal to BagelSteramReader.ReadLine() every time, overwriting the previous value of TextBox1.Text. Try TextBox1.Text += BagelStreamReader.ReadLine() + '\n'
Edit: Though I must steal agree with Hans Passant's commented idea on this; If you want an more efficient algorithm, File.ReadAllLines() even saves you time and money...though I didn't know of it myself. Darn .NET, having so many features...
I wrote a program to both write to and read from a text file. To write the lines of a list box to a text file I used the following code:
Private Sub txtWriteToTextfile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtWriteToTextfile.Click
Dim FileWriter As StreamWriter
FileWriter = New StreamWriter(FileName, False)
' 3. Write some sample data to the file.
For i = 1 To lstNamesList.Items.Count
FileWriter.Write(lstNamesList.Items(i - 1).ToString)
FileWriter.Write(Chr(32))
Next i
FileWriter.Close()
End Sub
And to read and write the contents of the text file and write to a multi-line text box (you just need to set the multiple lines property of a text box to true) I used the following code. I also had to do some extra coding to break the individual words from the long string I received from the text file.
Private Sub cmdReadFromTextfile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReadFromTextfile.Click
Dim sStringFromFile As String = ""
Dim sTextString As String = ""
Dim iWordStartingPossition As Integer = 0
Dim iWordEndingPossition As Integer = 0
Dim iClearedTestLength As Integer = 0
Dim FileReader As StreamReader
FileReader = New StreamReader(FileName)
sStringFromFile = FileReader.ReadToEnd()
sTextString = sStringFromFile
txtTextFromFile.Text = ""
Do Until iClearedTestLength = Len(sTextString)
iWordEndingPossition = CInt(InStr((Microsoft.VisualBasic.Right(sTextString, Len(sTextString) - iWordStartingPossition)), " "))
txtTextFromFile.Text = txtTextFromFile.Text & (Microsoft.VisualBasic.Mid(sTextString, iWordStartingPossition + 1, iWordEndingPossition)) & vbCrLf
iWordStartingPossition = iWordStartingPossition + iWordEndingPossition
iClearedTestLength = iClearedTestLength + iWordEndingPossition
Loop
FileReader.Close()
End Sub