Я пытаюсь написать надстройку Word, которая использует CustomTaskPane.Я могу создать CustomTaskPane и синхронизировать его между открытыми документами, и я не получаю ошибок, пока использую меню Word, когда добавляю новый или открываю существующий документ.Однако, если я добавляю новый документ через кнопку ленты, которая вызывает Globals.ThisAddIn.Application.Documents.Add()
, я начинаю получать исключения COMException при закрытии документов.
Проблема возникает, когда я добавляю новый документ, используя событие нажатия кнопки в 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()
.Я искал ошибку, но большинство проблем возникает, когда люди пытаются использовать Word Interop на сервере или на странице ASP.net, но я получаю это на своем компьютере разработчика.Кроме того, если я использую метод Document.Add()
, состояние проверки кнопки «Показать» отображается некорректно (если у меня открыта панель CustomTaskPane в одном документе, затем нажмите кнопку «Создать документ» на ленте, кнопка «Показать» нового документа будет проверена дажехотя панель задач не отображается. Если я переключаюсь в другое окно, а затем снова переключаюсь на новый документ, проверяется статус кнопки, когда она не проверяется.
Я попытался перебрать Globals.ThisAddIn.CustomTaskPanes
, чтобы проверить,есть несоответствие между свойствами ctp.Window.Hwnd
, но, насколько я могу судить, каждый ctp.Window
имеет свой уникальный Hwnd
. Я получаю сообщение, даже когда открыты другие документы и окна.
Вот соответствующие файлы кода 2. Я использую CurrentCustomTaskPane, чтобы кнопка ленты могла синхронизироваться со свойством Visible панели задач.
ThisAddIn.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);
}
}
CtpWordRibbon.cs:
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();
}
Очевидно, что есть разница между тем, как Word обрабатывает добавление нового документа через меню Word и добавление его с помощью Application.Documents.Add()
метод.Как я могу проверить, будет ли свойство ActiveDocument
вызывать исключение COMException, прежде чем я на самом деле получу к нему доступ?Или есть лучший способ создать новый документ через ленту или обработать событие OnNewDocument
, чтобы я не получил эти ошибки?