我有一个使用VSTO和互操作的Microsoft Word加载项。如果针对已打开的文档触发DocumentOpen
事件,则我的代码会出现问题。我已经能够通过打开文档doc1,打开另一个文档doc2,然后再次尝试打开doc1来一致地复制它。
Doc1已经明显打开,但是对于doc1再次触发了DocumentOpen事件。这是一个预期的设计,如果是这样,有一个简单的方法,我可以判断是否为已经打开的文件触发了事件?
private void ThisAddIn_Startup(object sender, System.EventArgs a)
{
try
{
this.Application.DocumentOpen +=
new MSWord.ApplicationEvents4_DocumentOpenEventHandler(Application_DocumentOpen);
}
}
private void Application_DocumentOpen(MSWord.Document document)
{
HandleOpenedDocument(document);
}
答案 0 :(得分:4)
据我所知,通过阅读documentation并进行一些实证研究,如果出现以下情况,DocumentOpen
事件就会被触发:
但是,如果你:
所以规则可能是这样的:“如果你在事件上反复打开同一个文件只会被触发一次,但是,当你打开一个不同于最近打开的文件的文件时,事件是无论该文档是否已在正在运行的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!");
}
}
}
}
希望这有帮助! :)