对于 VSTO Word 加载项:是否在另存为后触发了事件?
For VSTO Word add-in: Is there an event fired after Save-As?
注意:虽然我的问题与 VSTO Word post save event, the aims and goals (and resultant required code) are different. The OP in VSTO Word post save event 状态相同:
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。
笔记结束
我有一个用于 Word 的 VSTO
加载项,旨在处理 RTF 文件(并且仅是 RTF 文件)的各种元素。加载项由功能区按钮调用。如果用户打开一个 RTF 文档,然后执行 save-as
,我想捕获一个事件,以便我可以检查为另存为选择的文件名,并禁用调用我的加载项的按钮,如果扩展不是 .RTF
.
在我的功能区 class 功能区加载方法(在我的功能区 class 的设计器文件中断言的事件处理方法: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
发生之前触发,而不是之后。我还在这个色带加载方法中放置了一个断点。另存为后不再执行(我并不惊讶)
我错过了什么吗?对于我的 VSTO Word 加载项,在我的功能区 class 中可捕获的 save-as
事件之后是否会触发一个事件,该事件将提供为 save-as
选择的文件的名称?
更新我的代码以反映 Cindy Meister 的回答
归功于 Joseph Fox on the Microsoft Developer's Network. My code derived from Document Save Event
注意:我的 VSTO 功能区 class 名为 ClsLesCaveat
。这是一个包含两个按钮的新组,位于现有的 Insert
table 中。它仅使用 VS Pro 2017 中的 VSTO 设计器创建。
对我来说,我的功能区按钮需要在两种情况下禁用:
1) 如果有人使用没有 .RTF 扩展名的 Word 打开文件,我的功能区按钮应该被禁用
2) 如果有人使用 Word 打开 .RTF 文件(我的按钮已启用),但如果他们对非 .RTF 文件执行另存为操作,则应为非 .RTF 文件禁用我的功能区按钮。 RTF 文档
注意:不要关心保存,因为我的功能区按钮 enabled/disabled 在打开或另存为时
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
}
}
否,没有捕获任何保存或保存后操作的事件。唯一与储蓄相关的是DocumentBeforeSave。
DocumentBeforeSave 确实提供了参数,让开发人员可以抑制内置 UI(另存为对话框)以及取消触发事件的操作。这允许开发人员提供他们自己的保存 (as) 接口,will 可以确定文档何时被保存 (as) 并根据文件名、扩展名或其他任何内容采取所需的任何操作标准是。
也可以使用 Word 的内置另存为对话框,而不是创建自己的对话框,尽管这在 C# 中有点迂回,因为它需要使用 PInvoke。下面是一个示例,可以让您了解它是如何工作的(我在移动设备上未进行测试):
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);
}
列出了可以使用的可用对话框参数 here。
注意:虽然我的问题与 VSTO Word post save event, the aims and goals (and resultant required code) are different. The OP in VSTO Word post save event 状态相同:
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。
笔记结束
我有一个用于 Word 的 VSTO
加载项,旨在处理 RTF 文件(并且仅是 RTF 文件)的各种元素。加载项由功能区按钮调用。如果用户打开一个 RTF 文档,然后执行 save-as
,我想捕获一个事件,以便我可以检查为另存为选择的文件名,并禁用调用我的加载项的按钮,如果扩展不是 .RTF
.
在我的功能区 class 功能区加载方法(在我的功能区 class 的设计器文件中断言的事件处理方法: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
发生之前触发,而不是之后。我还在这个色带加载方法中放置了一个断点。另存为后不再执行(我并不惊讶)
我错过了什么吗?对于我的 VSTO Word 加载项,在我的功能区 class 中可捕获的 save-as
事件之后是否会触发一个事件,该事件将提供为 save-as
选择的文件的名称?
更新我的代码以反映 Cindy Meister 的回答
归功于 Joseph Fox on the Microsoft Developer's Network. My code derived from Document Save Event
注意:我的 VSTO 功能区 class 名为 ClsLesCaveat
。这是一个包含两个按钮的新组,位于现有的 Insert
table 中。它仅使用 VS Pro 2017 中的 VSTO 设计器创建。
对我来说,我的功能区按钮需要在两种情况下禁用:
1) 如果有人使用没有 .RTF 扩展名的 Word 打开文件,我的功能区按钮应该被禁用
2) 如果有人使用 Word 打开 .RTF 文件(我的按钮已启用),但如果他们对非 .RTF 文件执行另存为操作,则应为非 .RTF 文件禁用我的功能区按钮。 RTF 文档
注意:不要关心保存,因为我的功能区按钮 enabled/disabled 在打开或另存为时
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
}
}
否,没有捕获任何保存或保存后操作的事件。唯一与储蓄相关的是DocumentBeforeSave。
DocumentBeforeSave 确实提供了参数,让开发人员可以抑制内置 UI(另存为对话框)以及取消触发事件的操作。这允许开发人员提供他们自己的保存 (as) 接口,will 可以确定文档何时被保存 (as) 并根据文件名、扩展名或其他任何内容采取所需的任何操作标准是。
也可以使用 Word 的内置另存为对话框,而不是创建自己的对话框,尽管这在 C# 中有点迂回,因为它需要使用 PInvoke。下面是一个示例,可以让您了解它是如何工作的(我在移动设备上未进行测试):
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);
}
列出了可以使用的可用对话框参数 here。