Results 1 to 8 of 8

Thread: BackGroundWorker and ListView

  1. #1

    Thread Starter
    Member
    Join Date
    Jul 2010
    Posts
    43

    BackGroundWorker and ListView

    Hi,

    I am trying to populate a listview from a sql table and at the same time run a progress bar. Currently my progressbar does't run and also the listview does not poulate. I believe there is something wrong with my arraylist but I can't figure it out. Please help. I am using VB.net.

    HTML Code:
    Dim lsvdupsitemlist As New List(Of ListViewItem)
        Private Sub FindDupsBGW_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles FindDupsBGW.DoWork
            Try
    
                'Connect to Laserfiche
                Dim app As LFApplication = New LFApplication
                Dim serv As LFServer = app.GetServerByName("")
                Dim db As LFDatabase = serv.GetDatabaseByName("")
                Dim conn As New LFConnection
                conn.UserName = ""
                conn.Password = ""
                conn.Create(db)
    
                'Use to cause Permission denied error and checks to see if folder path exists
                Try
                    Dim CheckFolderExists As LFFolder = db.GetEntryByPath(SearchTextBox.Text)
                    Dim st As ILFFolderStats = CType(CheckFolderExists.Stats(False), ILFFolderStats)
    
                Catch
                    MessageBox.Show("Unable to access folder. Folder access is not authorized. Please re-enter the folder path or contact your system Administrator.", "Access Denied:", MessageBoxButtons.OK, MessageBoxIcon.Stop)
                    e.Cancel = True
                    Exit Sub
                End Try
    
                LFcnn = LFSQLDBConnect()
                LFcnn.Open()
                'Checks to see if table already exists in SQL. If yes, drop and recreate.
                'Try
                Dim format As String = "HHmmss"
                Dim SQLTable As String = "T" + strip(GetdateLabel.Text)
                Dim command0 As SqlClient.SqlCommand = New SqlClient.SqlCommand("IF EXISTS(SELECT name FROM [LFDUPS]..sysobjects WHERE name = N'" & SQLTable & "' AND xtype='U') DROP TABLE " & SQLTable & "", LFcnn)
                Dim command1 As SqlClient.SqlCommand = New SqlClient.SqlCommand("create table " & SQLTable & " (Tocid nvarchar(max), FolderName nvarchar(max), FullPath nvarchar(max))", LFcnn)
                command0.ExecuteNonQuery()
                command1.ExecuteNonQuery()
                ' Catch ex As Exception
                'MessageBox.Show(ex.ToString)
                ' End Try
    
                'Check Cancel command
                If (FindDupsBGW.CancellationPending) Then
                    e.Cancel = True
                    Exit Sub
                End If
    
                'Performs search within Laserfiche
    
                Dim SearchVar As String = "ThurstonCounty\" + SearchTextBox.Text
                ''Dim SQLTable As String = "T" + strip(GetdateLabel.Text)
                Dim NewSearch As LFSearch = db.CreateSearch
                'NewSearch.Command = "{LF:Lookin=""" + SearchVar + """,subfolders=y} & {LF:Name=""*"",Type=""D""}"
                NewSearch.Command = "{LF:Lookin=""" + SearchVar + """} & {LF:Name=""*"",Type=""F""}"
                'NewSearch.Command = "{LF:LOOKIN=""ThurstonCounty\_Central_Services\Projects\7117-25190 ARC Phase 1\Contract Documents\Change Order Requests Proposal (PCO's)""} & {LF:Name=""*"", Type=""F""}"
                NewSearch.BeginSearch(True)
                Dim allhits As ILFCollection = NewSearch.GetSearchHits
                For Each hit As LFSearchHit In allhits
                    Dim entryhits As ILFEntry = hit.Entry
                    Dim command3 As SqlClient.SqlCommand = New SqlClient.SqlCommand("Insert INTO " & SQLTable & " (TocId, FolderName, Fullpath) Values('" & CleanSQLValue(entryhits.ID) & "','" & CleanSQLValue(entryhits.Name) & "','" & CleanSQLValue(entryhits.FullPath.ToString) & "')", LFcnn)
                    command3.ExecuteNonQuery()
    
                Next
                'End If
                LFcnn.Close()
                LFcnn.Dispose()
                conn.Terminate()
            Catch ex As Exception
                'MessageBox.Show("Unable to search Folder." + " " + "  Please re-enter Folder Path or contact your System Administrator.", "Search Error:", MessageBoxButtons.OK, MessageBoxIcon.Error)
                MessageBox.Show("Unable to search Folder." + ex.ToString + "  Please re-enter Folder Path or contact your System Administrator.", "Search Error:", MessageBoxButtons.OK, MessageBoxIcon.Error)
                e.Cancel = True
            End Try
    
    
            'add to listview
            'If ToDateTimePicker.Checked = False AndAlso FromDateTimePicker.Checked = False Then
            SearchByDateval = "and created between '1/01/2000' and" + " " + "'" + Format(Date.Now, "MM/dd/yyyy") + "'"
            'Else
    
            'SearchByDateval = "and created between" & " '" & Format(FromDateTimePicker.Value, "MM/dd/yyyy") & " '" & " and" + " " & " '" & Format(ToDateTimePicker.Value.AddDays(1), "MM/dd/yyyy") & " '"
            'End If
    
            'Populate ListView with results. Displays potential duplicates from Diferent folders within laserfiche.
            Try
    
                LFcnn = LFSQLDBConnect()
                LFcnn.Open()
                Dim SQLTable As String = "T" + strip(GetdateLabel.Text)
                Dim LFsqlresult As Object
                Dim command01 As SqlClient.SqlCommand = New SqlClient.SqlCommand("select count(*) from LFContents," & SQLTable & " where LFContents.Name in (select LFContents.Name from LFContents," & SQLTable & " where LFContents.PARENTid = " & SQLTable & " " & ".TocId" & " group by LFContents.Name having count(*) > 1 ) AND ETYPE = -2", LFcnn)
                command01.CommandType = CommandType.Text
                command01.CommandTimeout = 600
                command01.ExecuteScalar()
                LFsqlresult = command01.ExecuteScalar
                If LFsqlresult = 0 Then
                    ResultsListView.Items.Add("No Duplicates Found")
                    ProgressBar.Hide()
                    ExportToFileButton.Enabled = False
                    LFcnn.Close()
                    Exit Sub
                Else
    
                    Dim LFsqlresultRead As Object
                    Dim command02 As SqlClient.SqlCommand = New SqlClient.SqlCommand("select distinct LFContents.Name as EntryName, LFContents.edoc_size as FileSize, LFContents.Created as CreationDate, " & SQLTable & " " & ".Fullpath from LFContents, " & SQLTable & " where LFContents.Name in (select LFContents.Name from LFContents," & SQLTable & "  where LFContents.PARENTid = " & SQLTable & " " & ".TocId" & " group by LFContents.Name having count(*) > 1 ) and LFContents.PARENTid  = " & SQLTable & " " & ".TocId" & " " & " AND ETYPE = -2" & " " & SearchByDateval & "Union select distinct LFContents.Name, LFContents.edoc_size as FileSize, LFContents.Created, " & SQLTable & " " & ".Fullpath from LFContents, " & SQLTable & "  where LFContents.Name like '%(%' and LFContents.PARENTid  = " & " " & SQLTable & " " & ".TocId" & " " & "AND ETYPE = -2" & " " & SearchByDateval & " order by LFContents.Name ", LFcnn)
                    command02.CommandType = CommandType.Text
                    command02.CommandTimeout = 600
                    LFsqlresultRead = command02.ExecuteReader
    
                    'lsvdupsitems.SubItems.Clear()
    
                    While LFsqlresultRead.Read()
                        If LFsqlresultRead.Item(0).ToString <> "" Then
                            'Column name of ListView needs to be the same as SQl table coulumn names
                            Dim lsvdupsitems As New ListViewItem '= ResultsListView.Items.Add(".")
                           
    
                            lsvdupsitemlist.Add(lsvdupsitems)
                            FindDupsBGW.ReportProgress(LFsqlresultRead.Item(0))
                            Threading.Thread.Sleep(100)
                        End If
                    End While
                End If
                LFcnn.Close()
                LFcnn.Dispose()
    
            Catch ex As Exception
                MessageBox.Show("Unable to populate List of results." + " " + ex.Message + "Please try again or contact your System Administrator.", "Database Connection Error:", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
    
        End Sub
    
        Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles FindDupsBGW.ProgressChanged
    
            ProgressBar.Value = e.ProgressPercentage
            ResultsListView.Items.AddRange(lsvdupsitemlist.toarray())
    
        End Sub
    
    
        Dim SearchByDateval As String
        Private Sub FindDupsBGW_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles FindDupsBGW.RunWorkerCompleted
            If e.Cancelled = True Then
                ProgressBar.Hide()
                ExportToFileButton.Enabled = False
                Exit Sub
            Else
                CancelButton.Enabled = False
               
            End If
            TimeLapseTimer.Stop()
            ProgressBar.Hide()
            ExportToFileButton.Enabled = True
            AutoFitListView(ResultsListView)
            LFcnn.Close()
            LFcnn.Dispose()
        End Sub

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: BackGroundWorker and ListView

    I would suggest that you follow the CodeBank link in my signature and check my thread on Using The BackgroundWorker. Post #4 has two code examples that populate a ListBox, one that does it one item at a time as the background processing occurs and one that does it in a batch when the background processing has finished. Your situation is analogous. You should be passing the item you want added when you call ReportProgress each time and getting it back in the ProgressChanged event handler, just as I do in that example. As for the ProgressBar, just call its Refresh method in the ProgressChanged event handler if required.

    Just note that the second option, i.e. adding the items in a batch when you're done processing, will be significantly faster then adding one item at a time.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    Member
    Join Date
    Jul 2010
    Posts
    43

    Re: BackGroundWorker and ListView

    Hi,

    Thankyou for your response. I tried the batch method with a listview instead of a listbox and got the error below. Is there a way to use a listview instead?

    Overload resolution failed because no accessible 'AddRange' can be called with these arguments:
    'Public Sub AddRange(items As System.Windows.Forms.ListView.ListViewItemCollection)': Value of type '1-dimensional array of String' cannot be converted to 'System.Windows.Forms.ListView.ListViewItemCollection'.
    'Public Sub AddRange(items() As System.Windows.Forms.ListViewItem)': Value of type '1-dimensional array of String' cannot be converted to '1-dimensional array of System.Windows.Forms.ListViewItem' because 'String' is not derived from 'System.Windows.Forms.ListViewItem'.

    HTML Code:
    Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
            Dim fileNames As String() = IO.Directory.GetFiles(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
            For index As Integer = 0 To fileNames.GetUpperBound(0) Step 1
                fileNames(index) = IO.Path.GetFileName(fileNames(index))
            Next index
            e.Result = fileNames
    
        End Sub
    
        Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
      
    
    
        End Sub
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            Dim fileNames As String() = DirectCast(e.Result, String())
            Me.ListView1.Items.AddRange(fileNames)
       End Sub
    End Class

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: BackGroundWorker and ListView

    Of course there is but, if you are going to use a ListView, you have to give the ListView what it expects. You are calling ListView.Items.AddRange. What does that method expect you to pass in? That is what you have to pass in. What are you currently passing in? Here's a clue: the error message you copied into this thread answers both those questions. So, you're task is simple: write some code to create what you need from what you have got.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5

    Thread Starter
    Member
    Join Date
    Jul 2010
    Posts
    43

    Re: BackGroundWorker and ListView

    Hi,

    I am not sure what I am doing wrong here. I am still getting an error. Please help.

    HTML Code:
    Private Sub FindDupsBGW_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles FindDupsBGW.DoWork
    
     While LFsqlresultRead.Read()
                        If LFsqlresultRead.Item(0).ToString <> "" Then
    
                            'Column name of ListView needs to be the same as SQl table coulumn names
                            Dim duplist As New List(Of ListViewItem)
                            Do
                                Dim dupitem As New ListViewItem
                                dupitem.Text = LFsqlresultRead("EntryName")
                                dupitem.SubItems.Add(LFsqlresultRead("FileSize"))
                                dupitem.SubItems.Add(LFsqlresultRead("Creationdate"))
                                dupitem.SubItems.Add(LFsqlresultRead("FullPath"))
                                worker.ReportProgress(0, dupitem)
                                'Threading.Thread.Sleep(100)
                            Loop
                        End If
                    End While
                    'Next
                End If
                LFcnn.Close()
                LFcnn.Dispose()
    
            Catch ex As Exception
                MessageBox.Show("Unable to populate List of results." + " " + ex.Message + "Please try again or contact your System Administrator.", "Database Connection Error:", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
    
    
        End Sub
        Private Sub FindDupsBgw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles FindDupsBGW.ProgressChanged
                    Dim duplist As New List(Of ListViewItem)
            duplist = CType(e.UserState, List(Of ListViewItem))
            Me.ResultsListView.Items.Add(duplist.ToArray)
        End Sub

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: BackGroundWorker and ListView

    If I didn't know better I would think you hadn't actually looked at my CodeBank thread. I pointed you to two examples in that thread. One example populates the control one item at a time by getting one item at a time, passing that item to ReportProgress and adding that item on ProgressChanged. The other example creates a list of items and adds them in a batch on RunWorkerCompleted. Which of those are you following? The answer is neither. You are creating a list and then using ReportProgress and ProgressChanged, which is half one and half the other. Decide which way you want to do it and follow the appropriate example. Unless there is a big gap between the creation of each item, which there isn't, I would recommend the batch option, i.e. use RunWorkerCompleted and AddRange.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7

    Thread Starter
    Member
    Join Date
    Jul 2010
    Posts
    43

    Re: BackGroundWorker and ListView

    Hi,

    Thankyou, I was able to use the your first method flawlessly.

    HTML Code:
    Private Sub FindDupsBGW_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles FindDupsBGW.DoWork
     While LFsqlresultRead.Read()
                        If LFsqlresultRead.Item(0).ToString <> "" Then
                            'Check Cancel command
                            If (FindDupsBGW.CancellationPending) Then
                                e.Cancel = True
                                Exit Sub
                            End If
                            'Column name of ListView needs to be the same as SQl table coulumn names
    
                            Dim dupitem As New ListViewItem
                            dupitem.Text = LFsqlresultRead("EntryName")
                            dupitem.SubItems.Add(LFsqlresultRead("FileSize"))
                            dupitem.SubItems.Add(LFsqlresultRead("Creationdate"))
                            dupitem.SubItems.Add(LFsqlresultRead("FullPath"))
                            worker.ReportProgress(0, dupitem)
                            'Threading.Thread.Sleep(100)
    
                        End If
                    End While
                End If
                LFcnn.Close()
                LFcnn.Dispose()
    
    
    
    
            Catch ex As Exception
                MessageBox.Show("Unable to populate List of results." + " " + ex.Message + "Please try again or contact your System Administrator.", "Database Connection Error:", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
    
        End Sub
    
        Private Sub FindDupsBgw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles FindDupsBGW.ProgressChanged
            Dim Dupitem As New ListViewItem
            Dupitem = CType(e.UserState, ListViewItem)
            Me.ResultsListView.Items.Add(Dupitem)
    end sub

    However, when I try to convert what I have above to the second method, I am lost. Honestly, not sure where to begin, even with your hint. I have spent so many hours trying to research adding listviewitems to an array but am still confused. I guess I am confused on how to add multiple columns of the listview to a collection and then calling it in the RunComplete. I have tried a bunch of different things and failed. Please help.

    Thanks

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: BackGroundWorker and ListView

    You already know how to create a ListViewItem with subitems because you're already doing it. You just keep doing that but, instead of calling ReportProgress, you add the item to a List. When you're done, you assign the List to e.Result. In the RunWorkerCompleted event handler, you get the List back from e.Result and you add the items to the ListView in a batch.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width