C# 在文档失去保护后访问受保护的组件
我希望在DocumentOpen事件中修改文档,在适当的地方向现有文本添加一些内容控件,并更改格式。这可以正常工作,但在受保护的文档未受保护后触发DocumentOpen事件时会变得更加复杂:C# 在文档失去保护后访问受保护的组件,c#,ms-word,vsto,office-interop,word-2010,C#,Ms Word,Vsto,Office Interop,Word 2010,我希望在DocumentOpen事件中修改文档,在适当的地方向现有文本添加一些内容控件,并更改格式。这可以正常工作,但在受保护的文档未受保护后触发DocumentOpen事件时会变得更加复杂: private void ThisAddIn_Startup(object sender, EventArgs e) { Application.DocumentOpen += application_DocumentOpen; } private void application_Docume
private void ThisAddIn_Startup(object sender, EventArgs e)
{
Application.DocumentOpen += application_DocumentOpen;
}
private void application_DocumentOpen(Document doc)
{
doc.ContentControls.Add(
WdContentControlType.wdContentControlRichText,
doc.Range(doc.Content.Start, doc.Content.End - 1));
}
单击“启用编辑”开始“取消保护”文档的过程,此时将触发我定义的DocumentOpen事件。但是,由于事件似乎是在打开默认未受保护的窗口之前触发的,因此创建内容控件仍然视为不可用。当文档处于未受保护的过程中时,一个简单的示例不会成功:
private void ThisAddIn_Startup(object sender, EventArgs e)
{
Application.DocumentOpen += application_DocumentOpen;
}
private void application_DocumentOpen(Document doc)
{
doc.ContentControls.Add(
WdContentControlType.wdContentControlRichText,
doc.Range(doc.Content.Start, doc.Content.End - 1));
}
可以说,有没有办法加快解除保护的过程,并且仍然能够执行我的代码?或者,当文档编辑可用时,会触发另一个可预测的事件?我已经查看了与受保护模式相关的触发事件,但没有看到任何适合我需要的事件<很遗憾,代码>文档.Unprotect()和更改
文档.ActiveWindow.View.Type
也没有用,因为“受保护模式”似乎是一个完全不同的、不可编辑的窗口。这些格式修改要求在文档打开时进行,或在文档打开后尽快进行。这并不漂亮,但我最终解决了这个问题,定义了一个包含我要执行的代码的委托,该委托与每个文档的容器相关联,并检查委托是否可以在应用程序内执行。WindowActivate
:
public class DocumentContainer
{
public Action ProtectedDeferredExecution { get; set; }
public DocumentContainer(Action deferred)
{
ProtectedDeferredExecution = deferred;
}
}
public partial class ThisAddIn
{
private Dictionary<Document, DocumentContainer> DocumentContainerDict { get; set; }
private void ThisAddIn_Startup(object sender, EventArgs e)
{
DocumentContainerDict = new Dictionary<Document, DocumentContainer>();
Application.WindowActivate += application_WindowActivate;
Application.DocumentOpen += application_DocumentOpen;
Application.DocumentBeforeClose += application_DocumentClose;
}
private void application_DocumentOpen(Document doc)
{
// define code that is unsafe when document is protected
Action initialization = () =>
{
doc.ContentControls.Add(
WdContentControlType.wdContentControlRichText,
doc.Range(doc.Content.Start, doc.Content.End - 1));
};
// if the current window isn't "protected", able to execute the unsafe code
if (Application.ActiveProtectedViewWindow == null)
{
initialization();
initialization = null;
}
// send either the unsafe delegate or null to the constructor
DocumentContainerDict.Add(doc, new VersioningDocumentContainer(initialization));
}
private void application_WindowActivate(Document doc, Window wn)
{
// skip execution if the window is still protected or isn't the view we want
if (wn.View.Type != WdViewType.wdPrintView || Application.ActiveProtectedViewWindow != null)
{
return;
}
DocumentContainer container;
// find the document container, if any, and the delegate to execute
if (DocumentContainerDict.TryGetValue(doc, out container)
&& container.ProtectedDeferredExecution != null)
{
container.ProtectedDeferredExecution();
container.ProtectedDeferredExecution = null;
}
}
// clean up
private void application_DocumentClose(Document doc, ref bool cancel)
{
DocumentContainerDict.Remove(doc);
}
}
公共类文档容器
{
公共操作ProtectedDeferredExecution{get;set;}
公共文档容器(操作延迟)
{
ProtectedDeferredExecution=延迟;
}
}
公共部分类ThisAddIn
{
专用字典DocumentContainerDict{get;set;}
私有void ThisAddIn_启动(对象发送方,事件参数e)
{
DocumentContainerDict=新字典();
Application.WindowActivate+=应用程序\u WindowActivate;
Application.DocumentOpen+=Application\u DocumentOpen;
Application.DocumentBeforeClose+=Application\u DocumentClose;
}
私有作废应用程序\u文档打开(文档文档)
{
//定义文档受保护时不安全的代码
操作初始化=()=>
{
doc.ContentControls.Add(
WdContentControlType.wdContentControlRichText,
单据范围(doc.Content.Start、doc.Content.End-1);
};
//如果当前窗口没有“保护”,则无法执行不安全代码
如果(Application.ActiveProtectedViewWindow==null)
{
初始化();
初始化=空;
}
//将不安全的委托或null发送给构造函数
添加(文档,新版本DocumentContainer(初始化));
}
私有作废应用程序\u WindowActivate(文档文档,窗口wn)
{
//如果窗口仍受保护或不是我们想要的视图,则跳过执行
如果(wn.View.Type!=WdViewType.wdPrintView | | Application.ActiveProtectedViewWindow!=null)
{
返回;
}
文件容器;
//查找文档容器(如果有)和要执行的委托
if(DocumentContainerDict.TryGetValue)(文档,外容器)
&&container.ProtectedDeferredExecution!=null)
{
container.ProtectedDeferredExecution();
container.ProtectedDeferredExecution=null;
}
}
//清理
私有作废应用程序\文档关闭(文档文档,参考文件取消)
{
DocumentContainerDict.Remove(文档);
}
}
其他元数据也可以很容易地在这个容器中定义(这就是我使用它的目的),因此我为使用外接程序创建的每个文档创建一个元数据。这并不漂亮,但我最终通过定义一个包含我要执行的代码的委托来解决这个问题,该委托与每个文档的容器相关联,并检查委托是否可以在
应用程序内执行。WindowActivate
:
public class DocumentContainer
{
public Action ProtectedDeferredExecution { get; set; }
public DocumentContainer(Action deferred)
{
ProtectedDeferredExecution = deferred;
}
}
public partial class ThisAddIn
{
private Dictionary<Document, DocumentContainer> DocumentContainerDict { get; set; }
private void ThisAddIn_Startup(object sender, EventArgs e)
{
DocumentContainerDict = new Dictionary<Document, DocumentContainer>();
Application.WindowActivate += application_WindowActivate;
Application.DocumentOpen += application_DocumentOpen;
Application.DocumentBeforeClose += application_DocumentClose;
}
private void application_DocumentOpen(Document doc)
{
// define code that is unsafe when document is protected
Action initialization = () =>
{
doc.ContentControls.Add(
WdContentControlType.wdContentControlRichText,
doc.Range(doc.Content.Start, doc.Content.End - 1));
};
// if the current window isn't "protected", able to execute the unsafe code
if (Application.ActiveProtectedViewWindow == null)
{
initialization();
initialization = null;
}
// send either the unsafe delegate or null to the constructor
DocumentContainerDict.Add(doc, new VersioningDocumentContainer(initialization));
}
private void application_WindowActivate(Document doc, Window wn)
{
// skip execution if the window is still protected or isn't the view we want
if (wn.View.Type != WdViewType.wdPrintView || Application.ActiveProtectedViewWindow != null)
{
return;
}
DocumentContainer container;
// find the document container, if any, and the delegate to execute
if (DocumentContainerDict.TryGetValue(doc, out container)
&& container.ProtectedDeferredExecution != null)
{
container.ProtectedDeferredExecution();
container.ProtectedDeferredExecution = null;
}
}
// clean up
private void application_DocumentClose(Document doc, ref bool cancel)
{
DocumentContainerDict.Remove(doc);
}
}
公共类文档容器
{
公共操作ProtectedDeferredExecution{get;set;}
公共文档容器(操作延迟)
{
ProtectedDeferredExecution=延迟;
}
}
公共部分类ThisAddIn
{
专用字典DocumentContainerDict{get;set;}
私有void ThisAddIn_启动(对象发送方,事件参数e)
{
DocumentContainerDict=新字典();
Application.WindowActivate+=应用程序\u WindowActivate;
Application.DocumentOpen+=Application\u DocumentOpen;
Application.DocumentBeforeClose+=Application\u DocumentClose;
}
私有作废应用程序\u文档打开(文档文档)
{
//定义文档受保护时不安全的代码
操作初始化=()=>
{
doc.ContentControls.Add(
WdContentControlType.wdContentControlRichText,
单据范围(doc.Content.Start、doc.Content.End-1);
};
//如果当前窗口没有“保护”,则无法执行不安全代码
如果(Application.ActiveProtectedViewWindow==null)
{
初始化();
初始化=空;
}
//将不安全的委托或null发送给构造函数
添加(文档,新版本DocumentContainer(初始化));
}
私有作废应用程序\u WindowActivate(文档文档,窗口wn)
{
//如果窗口仍受保护或不是我们想要的视图,则跳过执行
如果(wn.View.Type!=WdViewType.wdPrintView | | Application.ActiveProtectedViewWindow!=null)
{
返回;
}
文件容器;
/