据我通过阅读文档和做一些实证研究可以看出,如果发生以下情况,事件似乎DocumentOpen
会被触发:
- 您打开 doc1,然后是 doc2,然后再次打开 doc1
但是,如果您:
- 打开 doc1 然后再次打开 doc1,该事件仅在第一次打开 doc1 时触发。
因此,规则可能类似于:“如果您一遍又一遍地打开同一个文档,则该事件仅触发一次,但是,当您打开与最近打开的文档不同的文档时,将为新打开的文档触发该事件无论该文档是否已在正在运行的 Word 实例中打开。”
我一直在文档中寻找更多细节,但没有任何运气。但是,如果您真的想知道发生了什么,我建议您在 MSDN 论坛上提问,其中一些 MVP 可能会提供帮助。
然后你问:
有没有一种简单的方法可以判断是否为已打开的文档触发了事件?
是的,我认为:)
基本上,您可以在应用程序中保留一组打开的文档,并使用DocumentOpen
和DocumentBeforeClose
事件来维护该集合。知道当前打开了哪些文档,就可以轻松确定触发事件时文档是否已经打开 - 只需在集合中查找即可。
为了说明,我已经构建了一个示例实现,说明如何使用 Word Interop 来完成 - 据我所知,这应该几乎 1 到 1 映射到 VSTO。我在代码中提供了一些注释,因此应该很容易理解正在发生的事情。
using Microsoft.Office.Interop.Word;
using Application = Microsoft.Office.Interop.Word.Application;
namespace WordDocStats
{
internal class Program
{
private static readonly HashSet<Document> OpenDocuments = new HashSet<Document>();
private static void Main()
{
var wordApplication = new Application() { Visible = true };
// Listen for documents open
wordApplication.DocumentOpen += WordApplicationDocumentOpen;
// Listen for documents close
wordApplication.DocumentBeforeClose += WordApplicationDocumentBeforeClose;
Console.ReadLine();
wordApplication.Quit();
}
static void WordApplicationDocumentBeforeClose(Document doc, ref bool cancel)
{
OpenDocuments.Remove(doc);
Console.WriteLine(doc.Name + " closed!");
}
static void WordApplicationDocumentOpen(Document doc)
{
// If this returns true, the doc is not in the set of open documents, hence the doc is not already open
if(OpenDocuments.Add(doc))
{
OpenDocuments.Add(doc);
Console.WriteLine(doc.Name + " opened...");
}
// Otherwise, the doc is already in the set of open documents, hence we know the document is already open
else
{
Console.WriteLine(doc.Name + " is already open!");
}
}
}
}
希望这可以帮助!:)