我正在尝试编写一个使用CustomTaskPane的Word加载项。我能够创建CustomTaskPane并在打开的文档之间进行同步,只要在添加新文档或打开现有文档时使用Word菜单,就不会出错。但是,如果我通过调用Globals.ThisAddIn.Application.Documents.Add()
的功能区按钮添加新文档,则在关闭文档时开始获取COMExceptions。
问题似乎是当我使用CtpMainRibbon.cs中的按钮单击事件而不是通过Word菜单添加新文档时,Globals.ThisAddIn.Application.ActiveWindow
属性在关闭打开的文档后无效。在获取CurrentCustomTaskPane属性时,ActiveWindow在System.Runtime.InteropServices.COMException: 'This command is not available because no document is open.'
返回一个Microsoft.Office.Interop.Word.ApplicationClass.get_ActiveWindow()
。我已经搜索了错误,但是大多数问题是当人们尝试在服务器或ASP.net页面上使用Word Interop时,但是我在开发机器上遇到了这个问题。另外,如果我使用Document.Add()
方法,则“显示”按钮的检查状态无法正确显示(如果我在一个文档中打开了CustomTaskPane,然后单击功能区上的“新建文档”按钮,则新文档的“显示”按钮为
我尝试遍历Globals.ThisAddIn.CustomTaskPanes
以查看ctp.Window.Hwnd
属性之间是否存在不匹配,但据我所知,每个ctp.Window
都有自己的唯一{{1 }}。即使还有其他文档和窗口打开,我也会收到消息。
这是2个相关的代码文件。我使用CurrentCustomTaskPane,以便功能区按钮可以与任务窗格的Visible属性同步。
ThisAddIn.cs:
Hwnd
CtpWordRibbon.cs:
private const string TaskPaneTitle = "Main Custom Task Panel";
public static CustomTaskPane CurrentCustomTaskPane
{
get
{
return Globals.ThisAddIn.CustomTaskPanes
.FirstOrDefault(ctp => !ctp.Control.IsDisposed &&
Globals.ThisAddIn.Application.ActiveWindow != null &&
ReferenceEquals(ctp.Window, Globals.ThisAddIn.Application.ActiveWindow) &&
ctp.Title == TaskPaneTitle);
}
}
private void InternalStartup()
{
Startup += ThisAddIn_Startup;
Shutdown += ThisAddIn_Shutdown;
}
private void ThisAddIn_Startup(object sender, EventArgs e)
{
if (Application.Documents.Count > 0)
AddNewTaskPane(Application.ActiveDocument);
Word.ApplicationEvents4_Event event4 = Application;
event4.NewDocument += OnNewDocument;
event4.DocumentOpen += OnDocumentOpen;
event4.WindowActivate += ApplicationOnWindowActivate;
}
private static void ThisAddIn_Shutdown(object sender, EventArgs e) { }
private void OnNewDocument(Word.Document doc) => AddNewTaskPane(doc);
private void OnDocumentOpen(Word.Document doc) => AddNewTaskPane(doc);
private void ApplicationOnWindowActivate(Word.Document doc, Word.Window wn) => SetRibbonButtonToggle();
private void AddNewTaskPane(Word._Document doc)
{
RemoveOrphanedTaskPanes();
CustomTaskPane newPane = CustomTaskPanes.Add(new MainCustomTaskPanel(), TaskPaneTitle, doc.ActiveWindow);
newPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionLeft;
newPane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
newPane.Width = 700;
newPane.VisibleChanged += TaskPaneOnVisibleChanged;
}
private void TaskPaneOnVisibleChanged(object sender, EventArgs e) => SetRibbonButtonToggle();
private void SetRibbonButtonToggle()
{
if (CurrentCustomTaskPane != null)
Globals.Ribbons.CtpWordRibbon.RbnButtonShowTaskPane.Checked = CurrentCustomTaskPane.Visible;
}
private void RemoveOrphanedTaskPanes()
{
foreach (CustomTaskPane ctp in CustomTaskPanes)
{
if (ctp.Window == null || ctp.Control.IsDisposed)
CustomTaskPanes.Remove(ctp);
}
}
Word处理通过Word菜单添加新文档和使用private void RbnButtonShowCtp_Click(object sender, RibbonControlEventArgs e)
{
if (ThisAddIn.CurrentCustomTaskPane != null)
ThisAddIn.CurrentCustomTaskPane.Visible = ((RibbonToggleButton)sender).Checked;
}
private void RbnButtonCreateNewDocument_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.Application.Documents.Add();
}
方法添加文档之间的方式显然有区别。在实际访问它之前,如何检查Application.Documents.Add()
属性是否将引发COMException?还是有更好的方法通过功能区创建新文档,或处理ActiveDocument
事件以使我不会收到这些错误?