Click here to Skip to main content
15,894,172 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
i'm trying to export list view item to excel sheet, every thing work perfect but when I'm trying to do this in background worker i face this error :

An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code

Additional information: Cross-thread operation not valid: Control 'ListView1' accessed from a thread other than the thread it was created on.

i dint know how to fix this , please help me :)

this is my code :

VB
Private Sub PictureBox2_Click(sender As Object, e As EventArgs) Handles PictureBox2.Click
    Try
        saveFileDialog1.Filter = "Excel File|*.xlsx"
        saveFileDialog1.Title = "Save an Excel File"
        Application.EnableVisualStyles()
        If saveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            If saveFileDialog1.FileName <> "" Then
                PictureBox1.Visible = True
                BackgroundWorker1.RunWorkerAsync()

            End If
        End If
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub


Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    saveExcelFile(SaveFileDialog1.FileName)
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    PictureBox1.Visible = False
    MessageBox.Show("DONE !!")
End Sub

Public Sub saveExcelFile(ByVal FileName As String)
    'Try
    Dim xls As New Excel.Application
    Dim sheet As Excel.Worksheet
    Dim i As Integer
    xls.Workbooks.Add()
    sheet = xls.ActiveWorkbook.ActiveSheet
    Dim row As Integer = 1
    Dim col As Integer = 1
    For i = 0 To Me.ListView1.Columns.Count - 1
        sheet.Cells(1, i + 1) = Me.ListView1.Columns(i).Text
    Next
    For i = 0 To Me.ListView1.Items.Count - 1
        For j = 0 To Me.ListView1.Items(i).SubItems.Count - 1 ' here the ERROR !!
            sheet.Cells(i + 2, j + 1) = Me.ListView1.Items(i).SubItems(j).Text
        Next
    Next

    row += 1
    col = 1

    ' for the header
    sheet.Rows(1).Font.Name = "Microsoft Sans Serif"
    sheet.Rows(1).Font.size = 16
    sheet.Rows(1).Font.Bold = True
    sheet.Rows(1).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter
    Dim mycol As System.Drawing.Color = System.Drawing.ColorTranslator.FromHtml("#20b2aa")
    sheet.Rows(1).Font.color = mycol
    ' for all the sheet without header
    sheet.Range("a2", "z1000").Font.Name = "Arial"
    sheet.Range("a2", "z1000").Font.Size = 14
    sheet.Range("a2", "z1000").HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter

    sheet.Range("A1:X1").EntireColumn.AutoFit()
    sheet.Range("A1:X1").EntireRow.AutoFit()

    xls.ActiveWorkbook.SaveAs(FileName)
    xls.Workbooks.Close()
    xls.Quit()
    'Catch ex As Exception
    '    MsgBox(ex.Message)
    'End Try
End Sub
Posted
Updated 29-Apr-15 2:49am
v3
Comments
Ralf Meier 29-Apr-15 8:47am    
Hi,
I can't see where the ListView1-Access is in your Code. I think, there are some lines missing.
But when I look at your error-message : I suppose that you must invoke the listview (whereever it ist used).


Please excuse me - I think my glasses are dirty. Now I find it.
But invoke is not the right solution - sorry.
Try to write the listview-content you use in a variable and inside your thread work with this variables instead of the listview.
Rabeea Qabaha 29-Apr-15 8:50am    
thanks for replay.
i updated my question :)
please if you can help help me :)
Ralf Meier 29-Apr-15 8:51am    
I corrected my post - please take a look ...
Ralf Meier 29-Apr-15 8:53am    
But I am wondering why the accesses before your marking does now throw the exeption.
Ralf Meier 29-Apr-15 8:58am    
I took a look to the description of listview. There ist written, that all static memebers of the control are thread-safe - all instanced members (as for example your collection) not ...

 
Share this answer
 
Comments
CPallini 29-Apr-15 9:00am    
5.
Richard MacCutchan 29-Apr-15 9:02am    
Thanks; 5 for knowing how to Google. :laugh:
Hi,
Use a thread and from the you can access your UI thread from the called thread.

eg:
C#
 private void ackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
{
     ThreadPool.QueueWorkerProcress(new WaitCallback(saveExcelFile));
}

private void saveExcelFile(object obj)
{
         do your work();

        on updating the data to UI use the below code

         this.beginInvoke(new MethodInvoker(updateUI));

}
private void updateUI()
{
    your update UI code.
 
}
 
Share this answer
 
v2
Comments
Richard MacCutchan 29-Apr-15 9:02am    
Please ensure you format your code properly when posting answers; as I have done for you.
Rabeea Qabaha 29-Apr-15 9:21am    
can you add what you say in my code please .?
i don't understand you will :(
Richard MacCutchan 29-Apr-15 9:33am    
Edit the solution and you will see the markup.
Rabeea Qabaha 29-Apr-15 9:47am    
@Richard MacCutchan
please help me :(
Richard MacCutchan 29-Apr-15 10:15am    
Follow the link in the Solution above that I posted. It explains how to handle cross-thread issues in C#.
I have edited your code like I think ...
Please try if it is working.

Greetings
Ralf

VB
Private Sub PictureBox2_Click(sender As Object, e As EventArgs) Handles PictureBox2.Click
    Try
        SaveFileDialog1.Filter = "Excel File|*.xlsx"
        SaveFileDialog1.Title = "Save an Excel File"
        Application.EnableVisualStyles()
        If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            If SaveFileDialog1.FileName <> "" Then
                PictureBox2.Visible = True

                ListView_Columns = ListView1.Columns
                ListView_Items = ListView1.Items

                BackgroundWorker1.RunWorkerAsync()

            End If
        End If
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

Private ListView_Columns As System.Windows.Forms.ListView.ColumnHeaderCollection
Private ListView_Items As System.Windows.Forms.ListView.ListViewItemCollection


Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    saveExcelFile(SaveFileDialog1.FileName)
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    PictureBox2.Visible = False
    MessageBox.Show("DONE !!")
End Sub

Public Sub saveExcelFile(ByVal FileName As String)
    'Try
    Dim xls As New Excel.Application
    Dim sheet As Excel.Worksheet
    Dim i As Integer
    xls.Workbooks.Add()
    sheet = xls.ActiveWorkbook.ActiveSheet
    Dim row As Integer = 1
    Dim col As Integer = 1
    For i = 0 To ListView_Columns.Count - 1
        sheet.Cells(1, i + 1) = ListView_Columns(i).Text
    Next
    For i = 0 To ListView_Items.Count - 1
        For j = 0 To ListView_Items(i).SubItems.Count - 1 ' here the ERROR !!
            sheet.Cells(i + 2, j + 1) = ListView_Items(i).SubItems(j).Text
        Next
    Next

    row += 1
    col = 1

    ' for the header
    sheet.Rows(1).Font.Name = "Microsoft Sans Serif"
    sheet.Rows(1).Font.size = 16
    sheet.Rows(1).Font.Bold = True
    sheet.Rows(1).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter
    Dim mycol As System.Drawing.Color = System.Drawing.ColorTranslator.FromHtml("#20b2aa")
    sheet.Rows(1).Font.color = mycol
    ' for all the sheet without header
    sheet.Range("a2", "z1000").Font.Name = "Arial"
    sheet.Range("a2", "z1000").Font.Size = 14
    sheet.Range("a2", "z1000").HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter

    sheet.Range("A1:X1").EntireColumn.AutoFit()
    sheet.Range("A1:X1").EntireRow.AutoFit()

    xls.ActiveWorkbook.SaveAs(FileName)
    xls.Workbooks.Close()
    xls.Quit()

    'Catch ex As Exception
    '    MsgBox(ex.Message)
    'End Try
End Sub
 
Share this answer
 
Comments
Rabeea Qabaha 4-May-15 12:52pm    
thanks man :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900