代码之家  ›  专栏  ›  技术社区  ›  user7393973

保存前在Excel事件上显示Form2

  •  0
  • user7393973  · 技术社区  · 6 年前

    在Visual Studio 2017中,我正在使用 Form1 用户选择打开的Excel工作簿来侦听其 BeforeSave 事件。

    一旦该工作簿被保存,程序就会检测到它,然后从工作表中提取一些特定数据并打开 Form2 有了这些数据。

    我现在遇到的问题是当我装货时 形式2 保存前 事件的控件(如标签、按钮、文本框等)无法正确显示。它们看起来像带有背景色的方框。

    以下是我的代码简化并更改为重要部分:

    ' Reference:
    ' Microsoft Excel 15.0 Object Library
    Imports Microsoft.Office.Interop
    Public Class Form1
        Private xlApp As Excel.Application
        Public Shared WithEvents xlBook As Excel.Workbook
        Private Shared Sub Workbook_BeforeSave(SaveAsUI As Boolean, ByRef Cancel As Boolean) Handles xlBook.BeforeSave
            Form2.Show()
            'Form1.Close()
        End Sub
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
            Try
                xlApp = Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application")
                xlBook = xlApp.Workbooks(1)
            Catch
                MsgBox("Excel isn't opened.")
                Close()
            End Try
        End Sub
    End Class
    

    编辑: 使用 Application.Run(Form2) 工作(不知道为什么),但我也不能关闭 形式1 具有 Form1.Close() .

    1 回复  |  直到 6 年前
        1
  •  1
  •   Ahmed Abdelhameed    6 年前

    这个 BeforeSave 事件 像另一个一样 Interop.Excel 事件 在其他线程上引发。因此,您不能直接从它访问GUI线程。为了访问GUI线程(例如,访问表单控件、在主线程上创建表单等),需要调用 Invoke 带有委托的方法。

    更换 Form2.Show() 通过以下方法可以解决问题:

    Invoke(Sub() Form2.Show())
    

    但是,您应该创建一个 新的 要加载的窗体的实例。因此,您应该使用如下内容,而不是前一行:

    Private Sub Workbook_BeforeSave(SaveAsUI As Boolean,
                                    ByRef Cancel As Boolean) Handles xlBook.BeforeSave
        Invoke(Sub()
                   Dim frm As New Form2
                   frm.Show()
               End Sub)
    End Sub
    

    要了解有关WinForms线程安全调用的更多信息,请查看参考资料中的第一篇文章。


    参考文献: