【问题标题】:Accessing protected components after a document becomes unprotected在文档不受保护后访问受保护的组件
【发布时间】:2016-07-31 01:06:45
【问题描述】:

我希望在 DocumentOpen 事件中修改文档,在适当的地方向现有文本添加一些内容控件并更改格式。这可以正常工作,但在受保护的文档不受保护后触发 DocumentOpen 事件时会变得更加复杂:

单击“启用编辑”开始“取消保护”文档的过程,此时会触发我定义的 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));
}

有什么方法可以加快解除保护过程,可以这么说,并且仍然能够执行我的代码?或者当文档编辑可用时可以预见的另一个事件?我查看了与保护模式in the Microsoft documentation 相关的触发事件,但没有看到任何适合我需要的东西。 Document.Unprotect() 和更改 Document.ActiveWindow.View.Type 也很遗憾没有用,因为“保护模式”似乎是一个完全不同的、不可编辑的窗口。要求在打开文档时或之后尽快进行这些格式修改。

【问题讨论】:

    标签: c# ms-word vsto office-interop word-2010


    【解决方案1】:

    这不是很漂亮,但我最终解决了这个问题,方法是定义一个包含我要执行的代码的委托,与每个文档的容器相关联,并检查委托是否可以在 Application.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);
        }
    }
    

    其他元数据也可以轻松地在这个容器中定义(这是我使用它的目的),所以我为使用插件创建的每个文档创建一个。

    【讨论】:

      猜你喜欢
      • 2011-06-07
      • 1970-01-01
      • 2017-09-18
      • 2013-08-06
      • 2023-03-07
      • 1970-01-01
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多