带有 SaveFileDialog VB.NET 的 STAThreadAttribute

Posted

技术标签:

【中文标题】带有 SaveFileDialog VB.NET 的 STAThreadAttribute【英文标题】:STAThreadAttribute with SaveFileDialog VB.NET 【发布时间】:2014-11-18 13:19:02 【问题描述】:

我有一个将 ListView 导出到 Excel 工作表的应用程序,我试图在后台执行此操作,但 SaveFileDialog.showdialog() 中出现错误。这是错误:

发生“System.Threading.ThreadStateException”类型的异常 在 System.Windows.Forms.dll 中,但未在用户代码中处理

附加信息:在进行 OLE 调用之前,必须将当前线程设置为单线程单元 (STA) 模式。确保您的 Main 函数上标记了 STAThreadAttribute。仅当将调试器附加到进程时才会引发此异常。

这是我的代码:

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    BackgroundWorker1.RunWorkerAsync()
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
                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 = "Cooper Black"
        sheet.Rows(1).Font.size = 12
        sheet.Rows(1).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter
        Dim mycol As System.Drawing.Color = System.Drawing.ColorTranslator.Fromhtml("#148cf7")
        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 = 13
        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

    End Try
End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
     Try

        Dim saveFileDialog1 As New SaveFileDialog
        saveFileDialog1.Filter = "Excel File|*.xlsx"
        saveFileDialog1.Title = "Save an Excel File"
        saveFileDialog1.ShowDialog()
        If saveFileDialog1.FileName <> "" Then
            saveExcelFile(saveFileDialog1.FileName)
        End If

    Catch ex As Exception

    End Try
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    MsgBox("done")
End Sub

【问题讨论】:

【参考方案1】:

您可以将与SaveFileDialog1 相关的所有内容移动到Button3_Click 并将文件名存储在私有变量中,以便以后在BackgroundWorker1_DoWork 中使用。

Private _filename As String

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    SaveFileDialog1.Title = "Save Excel File"
    SaveFileDialog1.Filter = "Excel files (*.xls)|*.xls|Excel Files (*.xlsx)|*.xslx"
    SaveFileDialog1.ShowDialog()

    'exit if no file selected
    If SaveFileDialog1.FileName = "" Then
        Exit Sub
    End If

    _filename = SaveFileDialog1.FileName

    BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    ...
    book.SaveAs(_filename)
    ...
End Sub

【讨论】:

究竟是什么不工作?不会建吗?你遇到异常了吗? 如果你看到,我会更改我的代码,我尝试将 savegialog 1.file name 保存在变量中,我有同样的错误:( 但是现在你仍然在做有关 BackgroundWorker1_DoWork 中 SaveFileDialog 的所有事情... 我假设您现在遇到了一个错误,因为您尝试从 BackgroundWorker1_DoWork 访问 ListView1,但您无法从那里访问 UI 控件。【参考方案2】:

我把这段代码放在加载表单中,一切都很完美:

Control.CheckForIllegalCrossThreadCalls = False

【讨论】:

以上是关于带有 SaveFileDialog VB.NET 的 STAThreadAttribute的主要内容,如果未能解决你的问题,请参考以下文章

vb.net 保存列表框项目空行

带有 Savefiledialog 的 *** 异常

带有数据库的 vb.net

在 VB.NET 中使用带有匿名方法的 LINQ 的 ForEach

如何将带有枚举的 VB.net 接口转换为 C#

在 vb.net 中使用带有 shouldquote 的 csvhelper writer