Excel automation: Close event missing

前端 未结 4 916
南方客
南方客 2021-01-19 00:56

Another hi all,

I am doing Excel automation via Interop in C#, and I want to be informed when a workbook is closed. However, there is no Close event on the workbook

4条回答
  •  伪装坚强ぢ
    2021-01-19 01:40

    This is not my code, but this worked a treat for me:

    https://gist.github.com/jmangelo/301884

    Copy paste:

    using System;
    using Excel = Microsoft.Office.Interop.Excel;
    
    namespace Helpers.Vsto
    {
        public sealed class WorkbookClosedMonitor
        {
            internal class CloseRequestInfo
            {
                public CloseRequestInfo(string name, int count)
                {
                    this.WorkbookName = name;
                    this.WorkbookCount = count;
                }
    
                public string WorkbookName { get; set; }
    
                public int WorkbookCount { get; set; }
            }
    
            public WorkbookClosedMonitor(Excel.Application application)
            {
                if (application == null)
                {
                    throw new ArgumentNullException("application");
                }
    
                this.Application = application;
    
                this.Application.WorkbookActivate += Application_WorkbookActivate;
                this.Application.WorkbookBeforeClose += Application_WorkbookBeforeClose;
                this.Application.WorkbookDeactivate += Application_WorkbookDeactivate;
            }
    
            public event EventHandler WorkbookClosed;
    
            public Excel.Application Application { get; private set; }
    
            private CloseRequestInfo PendingRequest { get; set; }
    
            private void Application_WorkbookDeactivate(Excel.Workbook wb)
            {
                if (this.Application.Workbooks.Count == 1)
                {
                    // With only one workbook available deactivating means it will be closed
                    this.PendingRequest = null;
    
                    this.OnWorkbookClosed(new WorkbookClosedEventArgs(wb.Name));
                }
            }
    
            private void Application_WorkbookBeforeClose(Excel.Workbook wb, ref bool cancel)
            {
                if (!cancel)
                {
                    this.PendingRequest = new CloseRequestInfo(
                        wb.Name, 
                        this.Application.Workbooks.Count);
                }
            }
    
            private void Application_WorkbookActivate(Excel.Workbook wb)
            {
                // A workbook was closed if a request is pending and the workbook count decreased
                bool wasWorkbookClosed = true
                    && this.PendingRequest != null
                    && this.Application.Workbooks.Count < this.PendingRequest.WorkbookCount;
    
                if (wasWorkbookClosed)
                {
                    var args = new WorkbookClosedEventArgs(this.PendingRequest.WorkbookName);
    
                    this.PendingRequest = null;
    
                    this.OnWorkbookClosed(args);
                }
                else
                {
                    this.PendingRequest = null;
                }
            }
    
            private void OnWorkbookClosed(WorkbookClosedEventArgs e)
            {
                var handler = this.WorkbookClosed;
    
                if (handler != null)
                {
                    handler(this, e);
                }
            }
        }
    
        public sealed class WorkbookClosedEventArgs : EventArgs
        {
            internal WorkbookClosedEventArgs(string name)
            {
                this.Name = name;
            }
    
            public string Name { get; private set; }
        }
    }
    

    When I used it I changed it from return the name of the workbook to a reference to the workbook.

提交回复
热议问题