对于 VSTO Word 加载项:在另存为之后是否会触发事件? [英] For VSTO Word add-in: Is there an event fired after Save-As?

查看:91
本文介绍了对于 VSTO Word 加载项:在另存为之后是否会触发事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:虽然我的问题与 VSTO Word 后保存事件,目的和目标(以及由此产生的所需代码)是不同的.VSTO Word后期保存事件中的OP声明:

Note: Although my question is in the same ballpark as VSTO Word post save event, the aims and goals (and resultant required code) are different. The OP in VSTO Word post save event states:

文档保存到磁盘后,我需要捕获该事件,关闭文件,做我需要做的事情并重新打开它.

after the document is save to disk, I need to capture that event, close the file, do what I need to do and reopen it.

我的需求是不同的.查看我的 OP.

My needs are different. See my OP.

笔记结束

我有一个用于 Word 的 VSTO 加载项,旨在处理 RTF 文件(并且仅 RTF 文件)的各种元素.加载项由功能区按钮调用.如果用户打开一个 RTF 文档,然后执行 save-as,我想捕获一个事件,以便我可以检查为另存为选择的文件名并禁用调用我的添加的按钮-in 如果扩展名不是 .RTF.

I have a VSTO add-in for Word that is is designed to manipulate various elements of RTF files (and only RTF files). The add-in is invoked by a ribbon button. If the user opens an RTF document, and then does a save-as, I want to capture an event so I can examine the file name chosen for the save-as and disable the button that invokes my add-in if the extension is not .RTF.

在我的功能区类功能区加载方法中(在我的功能区类的设计器文件中声明的事件处理方法:this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.Ribbon1_Load)),我编写了各种可用的事件(例如,Globals.ThisAddIn.Application.DocumentChange += Application_DocumentChange;Globals.ThisAddIn.Application.DocumentOpen += Application_DocumentOpen;) 但所有可用的事件都在 save-as 发生之前触发,而不是之后触发.我还在这个功能区加载方法中放置了一个断点.另存为后不会再次执行(我并不感到惊讶)

In my ribbon class ribbon load method (The event handling method asserted in my ribbon class's designer file: this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.Ribbon1_Load)), I've coded up various available events (e.g., Globals.ThisAddIn.Application.DocumentChange += Application_DocumentChange; and Globals.ThisAddIn.Application.DocumentOpen += Application_DocumentOpen;) but all the events available are fired before the save-as happens, not after. I've also put a breakpoint in this ribbon load method. It is not executed again after the save-as (I'm not surprised)

我错过了什么吗?对于我的 VSTO Word 加载项,在 save-as 事件之后是否会触发一个事件,该事件可在我的功能区类中捕获,该事件将提供为 save-as 选择的文件的名称?

Am I missing something? For my VSTO Word add-in, is there an event fired after the save-as event that is capturable in my ribbon class that will provide the name of the file chosen for the save-as?

更新我的代码以反映 Cindy Meister 的回答

感谢 Joseph Fox 在 Microsoft 开发人员的网络.我的代码来自 文档保存事件

Credit to Joseph Fox on the Microsoft Developer's Network. My code derived from Document Save Event

注意:我的 VSTO 功能区类名为 ClsLesCaveat.这是一个带有两个按钮的新组,位于现有的 Insert 表中.它是在 VS Pro 2017 中仅使用 VSTO 设计器创建的.

Note: my VSTO ribbon class is named ClsLesCaveat. It is a new group with two buttons that sits in the existing Insert table. It was created using only the VSTO designer in VS Pro 2017.

对我来说,我的功能区按钮需要在两种情况下禁用:

For me, my ribbon buttons need to be disabled in two scenarios:

1) 如果有人使用没有 .RTF 扩展名的 Word 打开文件,我的功能区按钮应该被禁用

1) If someone opens a file using Word that does not have an .RTF extension, my ribbon buttons should be disabled

2) 如果有人使用 Word 打开 .RTF 文件(我的按钮已启用),但如果他们将另存为非 .RTF 文件,则应禁用该非 .RTF 文档的功能区按钮

2) If someone opens an .RTF file using Word (my buttons are enabled), but if they do a save-as to a non-.RTF file, my ribbon buttons should be disabled for that non-.RTF document

注意:不要在意保存,因为我的功能区按钮在打开或另存为时启用/禁用

Note: Don't care about save because my ribbon buttons are enabled/disabled at open or save-as otherwise

using System;
using System.IO;

namespace LesCaveatAddIn
{
    public partial class ThisAddIn
    {
        private bool allowSave = false;

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {

            this.Application.DocumentBeforeSave += Application_DocumentBeforeSave;
            this.Application.DocumentOpen += Application_DocumentOpen;
        }

        # On open, disable buttons, enable buttons only if file extension is .RTF
        private void Application_DocumentOpen(Microsoft.Office.Interop.Word.Document Doc)
        {
            string extension = (Path.GetExtension(Doc.FullName)).ToUpper();

            Type type = typeof(ClsLesCaveat);
            ClsLesCaveat ribbon = Globals.Ribbons.GetRibbon(type) as ClsLesCaveat;

            ribbon.objButtonAddFouoCaveat.Enabled = false;
            ribbon.objButtonAddLesCaveat.Enabled = false;

            if (extension.Equals(".RTF"))
            {
                ribbon.objButtonAddFouoCaveat.Enabled = true;
                ribbon.objButtonAddLesCaveat.Enabled = true;
            }
        }

        # On save-as, handle the save-as myself. Cancel the save-as (since I just handled it). Then, disable buttons, enable buttons only if the save-as file extension is .RTF.
        private void Application_DocumentBeforeSave(Microsoft.Office.Interop.Word.Document Doc, ref bool SaveAsUI, ref bool Cancel)
        {
            if (!allowSave)
            {
                allowSave = true;

                if (SaveAsUI)
                {
                    // Display Save As dialog
                    Microsoft.Office.Interop.Word.Dialog d = Globals.ThisAddIn.Application.Dialogs[Microsoft.Office.Interop.Word.WdWordDialog.wdDialogFileSaveAs];
                    object timeOut = 0;
                    d.Show(ref timeOut);
                }
                else
                {
                    // Save without dialog
                    Doc.Save();
                }

                allowSave = false;
                Cancel = true;

                string extension = (Path.GetExtension(Doc.FullName)).ToUpper();

                Type type = typeof(ClsLesCaveat);
                ClsLesCaveat ribbon = Globals.Ribbons.GetRibbon(type) as ClsLesCaveat;

                ribbon.objButtonAddFouoCaveat.Enabled = false;
                ribbon.objButtonAddLesCaveat.Enabled = false;

                if (extension.Equals(".RTF"))
                {
                    ribbon.objButtonAddFouoCaveat.Enabled = true;
                    ribbon.objButtonAddLesCaveat.Enabled = true;
                }
            }
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion
    }
}

推荐答案

不,没有事件可以捕获任何 Save 或 save after 操作.唯一与保存相关的是 DocumentBeforeSave.

No, there is no event to capture any Save or save after actions. The only one related to saving is DocumentBeforeSave.

DocumentBeforeSave 确实提供了参数,让开发人员可以取消内置 UI(另存为对话框)以及取消触发事件的操作.这允许开发人员提供自己的保存 (as) 接口,能够确定文档何时保存 (as) 并根据文件名、扩展名或任何条件执行所需的任何操作.

DocumentBeforeSave does provide arguments that let the developer suppress the built-in UI (SaveAs dialog box) as well as cancel the action that triggered the event. This allows developers to provide their own interface for saving (as) which will enable determining when the document is saved (as) and taking any actions desired, depending on the file name, extension or whatever the criteria are.

也可以使用 Word 的内置 SaveAs 对话框,而不是创建自己的对话框,尽管这在 C# 中有点绕,因为它需要使用 PInvoke.这是一个示例,可让您了解这是如何工作的(未在移动设备上进行测试):

It's also possible to work with Word's built-in SaveAs dialog box, rather than creating one's own, although this is a bit round-about in C# as it requires using PInvoke. Here's an example to give you an idea how this could work (not tested as I'm on a mobile device):

    private void ThisDocument_BeforeSave(object sender, object e)
    {
        //Suppress the built-in SaveAs interface (dialog box)
        e.SaveAsUi = false;
        //Cancel the default action
        e.Cancel = true;
        Word.Dialog dlg = wdApplication.Dialogs[Microsoft.Office.Interop.Word.WdWordDialog.wdDialogFileSaveAs];
        //Word dialog box parameters have to be accessed via Late-Binding (PInvoke) 
        //To get the path, use the Name property
        object oDlg = (object)dlg;
        object[] oArgs = new object[1];
        oArgs[0] = (object)@"";
        dlg.Show(ref missing);
        object fileName = oDlg.GetType().InvokeMember("Name", BindingFlags.GetProperty, null, oDlg, oArgs);
    }

列出了可以使用的可用对话框参数 此处.

The available dialog box arguments that can be used are listed here.

这篇关于对于 VSTO Word 加载项:在另存为之后是否会触发事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆