|
-
Nov 17th, 2011, 02:22 PM
#1
Thread Starter
Member
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
-
Nov 17th, 2011, 07:48 PM
#2
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.
-
Nov 18th, 2011, 01:30 PM
#3
Thread Starter
Member
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
-
Nov 18th, 2011, 09:33 PM
#4
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.
-
Nov 21st, 2011, 02:12 PM
#5
Thread Starter
Member
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
-
Nov 21st, 2011, 06:02 PM
#6
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.
-
Nov 22nd, 2011, 12:17 PM
#7
Thread Starter
Member
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
-
Nov 22nd, 2011, 06:30 PM
#8
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|