Projekt do pobrania tutaj: ProgressBar_BackGrW
Pokażę wam jak zrobić takie cudeńko które będzie kopiowało nam plik z punktu A do punktu B z możliwością anulowania kopiowania i z BackgroundWorkerem. Zaczynamy od dodania do naszej formy 4x Buttonów 3x Label i 1x ProgressBar
Kiedy ułożymy wszystkie kontrolki należ zmienić im tekst, Labele mają tekst „-”
Teraz z ToolBoxa potrzebujemy elementów: OpenFileDialog, BackgroundWorker, FolderBrowserDialog
Jeśli wszystko przebiegło prawidłowo na dole ekranu zobaczymy dodane elementy
Lewym przyciskiem myszy klikamy na element „BackgroundWorker1” i ustawiamy mu opcje WorkerReportsProgress na True i WorkerSupportsCancell na True
Teraz dodamy aktywność do przycisków wskazujących położenie pliku i miejsca docelowego kopii są to Button1 (Target file) i Button2 (Destiny directory)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Dim fileTargetLocation As String 'Zmienna przechowuje ścieżkę do pliku Dim Destinydirectory As String 'Zmienna przechowuje folder docelowy kopii Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Wywołanie dialogu wskazującego ścieżkę do pliku OpenFileDialog1.Title = "Select a file to copy" OpenFileDialog1.FileName = "" With OpenFileDialog1 If .ShowDialog() = DialogResult.OK Then fileTargetLocation = .FileName 'załadowanie ścieżki do zmiennej Label1.Text = fileTargetLocation.ToString End If End With End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 'Wywołanie dialogu wskazującego folder docelowy FolderBrowserDialog1.Description = "Select destiny directory" With FolderBrowserDialog1 If .ShowDialog() = DialogResult.OK Then Destinydirectory = .SelectedPath 'załadowanie ścieżki do zmiennej Label2.Text = Destinydirectory.ToString End If End With End Sub |
Reszta kodu wraz z opisem. Dodaje funkcjonalność dla reszty przycisków i BackgroundWorkera
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) _ Handles BackgroundWorker1.DoWork Dim parts As String() = fileTargetLocation.Split(New Char() {"\"c}) 'Dzieli plik Dim filename As String = parts(parts.Count - 1) 'pobiera z podzielonego pliku tylko nazwę pliku który kopiujemy Dim streamRead As New System.IO.FileStream(fileTargetLocation, System.IO.FileMode.Open) 'Otwiera nasz plik Dim streamWrite As New System.IO.FileStream(Destinydirectory + "\" + filename, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None) 'określa lokalizację docelową pliku i jego właściwości Dim lngLen As Long = streamRead.Length - 1 Dim byteBuffer(4096) As Byte 'inicjujemy buffer Dim intBytesRead As Integer 'If we use Async we need to Invoke setLabelTxt("Copy bytes : (0/" + (lngLen * 100).ToString + ")", Label3) 'Wyświetla ilość skopiowanych bytów 'Pętla kopii While streamRead.Position < lngLen If (BackgroundWorker1.CancellationPending = True) Then 'Przerywa wykonywanie BackgroundWorkera e.Cancel = True Exit While End If 'ładuje poziom na jakim jest kopiowanie do BackgroundWorker-Progress BackgroundWorker1.ReportProgress(CInt(streamRead.Position / lngLen * 100)) setLabelTxt("Copy bytes : (" + CInt(streamRead.Position).ToString + "/" + (lngLen * 100).ToString + ")", Label3) 'Wyświetla stan kopiowania w bytach intBytesRead = (streamRead.Read(byteBuffer, 0, 4096)) streamWrite.Write(byteBuffer, 0, intBytesRead) 'Zapisuje na dysku End While streamWrite.Flush() streamWrite.Close() streamRead.Close() End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Button1.Enabled = False 'blokuje przycisk 1 Button2.Enabled = False 'blokuje przycisk 2 BackgroundWorker1.RunWorkerAsync() 'wywołuje BackgroundWorkera, startuje go End Sub Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) _ Handles BackgroundWorker1.ProgressChanged ProgressBar1.Value = e.ProgressPercentage 'Wyświetla stan kopiowania End Sub Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) _ Handles BackgroundWorker1.RunWorkerCompleted If e.Cancelled = True Then 'komunikaty i elementy wykonywalny po ukończeniu kopii bądź jej przerwaniu MsgBox("Copy canceled!") Else MsgBox("Copy complete!") End If Button1.Enabled = True Button2.Enabled = True End Sub 'Wymagany sposób odwolywania się do formy podczas wykonywania działań asynchwonicznych takich jak BackgroundWorker Private Sub setLabelTxt(ByVal text As String, ByVal lbl As Label) If lbl.InvokeRequired Then lbl.Invoke(New setLabelTxtInvoker(AddressOf setLabelTxt), text, lbl) Else lbl.Text = text End If End Sub Private Delegate Sub setLabelTxtInvoker(ByVal text As String, ByVal lbl As Label) Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click If BackgroundWorker1.IsBusy Then ' przerywa wykonywanie BackgroundWorkera BackgroundWorker1.CancelAsync() End If End Sub |