Search code examples
vb.netbackgroundworkertoolstripmenu

vb.net statusbar text doesn't show


I have a code that searches for words in documents and fills a Listview with the found documents. Because the process can be rather lengthly I put a warning in the statusbar.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim foundList As Boolean
    Dim docImage As VariantType
    Dim PresetName As String
    ListView1.Items.Clear()
    ToolStripLabel1.Text = "Searching your documents, please wait."
    Try
        For Each row As DataRowView In CheckedListBox1.CheckedItems
            SearchRegX = row("RegX")
        Next
        If TextBoxFreeText.Text <> "" Then
            'look for a space in the search criteria, meaning there are more words
            Dim counter As Integer = TextBoxFreeText.Text.IndexOf(" ")
            If counter <> -1 Then
                'more words were entered to search
                Dim varSplit As Object
                varSplit = Split(TextBoxFreeText.Text, " ")
                'if more than two words are entered our regex doesnt work, so we exit the sub
                If varSplit.length > 2 Then
                    MsgBox("Your search criteria are to complex, use a maximum of two words",, Title)
                    Exit Sub
                End If

                iWords = NumericUpDown1.Value
                SearchRegX = "(?i)\b(?:" + varSplit(0) + "\W+(?:\w+\W+){0," + iWords + "}?" + varSplit(1) + "|" + varSplit(1) + "\W+(?:\w+\W+){0," + iWords + "}?" + varSplit(0) + ")\b"
            Else
                'just one word was entered
                SearchRegX = "(?i)\b" + TextBoxFreeText.Text + "\b"
            End If
        End If
            If SearchRegX = "" Then
            MsgBox("No Keyword was selected",, Title)
            Exit Sub
        End If

        If ListBox1.SelectedIndex > -1 Then
            For Each Item As Object In ListBox1.SelectedItems

                Dim ItemSelected = CType(Item("Path"), String)
                SearchFolder = ItemSelected

                'check if the folder of the archive still exists
                If (Not System.IO.Directory.Exists(SearchFolder)) Then
                    Dim unused = MsgBox("The archive " + SearchFolder.Substring(SearchFolder.Length - 5, Length) + " was not found",, Title)
                    Continue For
                End If
                Dim dirInfo As New IO.DirectoryInfo(SearchFolder)
                Dim files As IO.FileInfo() = dirInfo.GetFiles()
                Dim file As IO.FileInfo

                docImage = ImageList1.Images.Count - 1
                Dim items As New List(Of ListViewItem)

                For Each file In files
                    Dim filename As String = file.Name.ToString

                    If file.Extension = ".pdf" Or file.Extension = ".PDF" Then
                        foundList = PDFManipulation.GetTextFromPDF2(SearchFolder + filename, SearchRegX)
                        If foundList = True Then
                            If ListView1.FindItemWithText(filename.ToString) Is Nothing Then
                                items.Add(New ListViewItem(New String() {"", filename.ToString, SearchFolder.ToString}, docImage))
                            End If
                        End If
                    End If
                Next
                ListView1.Items.AddRange(items.ToArray)
            Next
            ToolStripLabel1.Text = ListView1.Items.Count.ToString + " Documents found."
        Else
            MsgBox("No archive was selected",, Title)
        End If

        SearchRegX = ""
        SearchFolder = ""

        'now save the search word to our textfile
        PresetName = TextBoxFreeText.Text
        If PresetName <> "" Then
            AddSearchWord()
        End If
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

End Sub

Somehow the text doesn't show in the statusbar before the process starts.

What should I change? I thought about a BackgroundWorker showing an image like waiting but the BackgroundWorker doesn't work because inside my Sub I call a function elsewhere.


Solution

  • This happens because the status strip control is not rendered properly before the pending workload is finished. To do so, you can refresh the status strip manually:

    StatusStrip1.Refresh()
    

    That is, if your only goal is to set the text. If you thought about running the code in the background so that the form is still responsive to user input, you'll need asynchronous programming using System.Threading.Tasks or System.Threading.Thread to run the code as a seperate thread. Be aware though that you may face difficulties when trying to access controls outside of the main thread.