.net Word VSTO加载项:删除GroupContentControl

.net Word VSTO加载项:删除GroupContentControl,.net,ms-word,vsto,.net,Ms Word,Vsto,我正在编写要添加的第一个单词。除此之外,我需要它使某些段落成为只读的,但不是永久性的。我正试图在运行时使用GroupContentControls(简称GCC)来达到这个效果 我已经完成了GCC的创建:这很简单,我只使用MSDN上的示例。但是,我似乎无法删除GCC 以下是我尝试过的代码: // Get a VSTO document object Document doc = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.

我正在编写要添加的第一个单词。除此之外,我需要它使某些段落成为只读的,但不是永久性的。我正试图在运行时使用GroupContentControls(简称GCC)来达到这个效果

我已经完成了GCC的创建:这很简单,我只使用MSDN上的示例。但是,我似乎无法删除GCC

以下是我尝试过的代码:

// Get a VSTO document object
Document doc = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveDocument); 
// Find the GCC in the document, by its ID
var controls = from GroupContentControl g in doc.Controls
               where g.ID.Equals(gcc_ID)
               select g;
// Safety check
if (controls == null)
    return;
if (controls.Count() == 0)
    return;
// Delete the GCC
var gc = controls.First();
gc.Delete(false);
为了简洁起见,我只列出了不起作用的代码。外接程序的其余部分的设计方式是,此代码仅在活动Word文档包含ID与gcc_ID匹配的GroupContentControl时运行

我在运行时遇到三种类型的错误:

  • 代码运行顺利,但GCC仍然存在,这让我相信我的一个安全测试失败了,代码过早返回
  • 代码在Delete调用时挂起,但有一个异常表示gc不是GroupContentControl
  • 在调试的早期,我也有一个gc变量赋值的异常,因为“controls”是“null”。。。这很奇怪,因为之前的安全测试没有失败。但我似乎无法重现那种特定的结果

知道GroupContentControl的ID后,有没有更简单更好的方法来删除它?我对.NET非常陌生,对VSTO也非常陌生,我可能遗漏了一些对您来说非常明显的东西。

调试这种东西时,第一步是使用“本机”Word对象(Microsoft.Office.Interop.Word),并确保该级别的一切正常工作

如果您不需要VSTO对象,就不要使用它们——坚持使用本机对象。我一点也不清楚为什么需要VSTO GroupContentControl对象——据我所知,对于组内容控件没有特殊的VSTO功能

尽管如此,如果您需要外接程序中的VSTO对象,在运行时,您必须在每次外接程序运行时创建它们。下面的代码就是这样做的。您应该从原生Word文档开始,因为稍后您将需要它

然后从本机Word文档创建VSTO文档对象。您基本上已经有了,但是应该从本机对象开始,而不是返回到Globals…ActiveDocument。请注意,我的代码在这方面与您的略有不同,因为我的目标是不同的.NET Framework。您应该继续使用
Globals.Factory.GetVstoObject…

下一步是获取本机组内容控件。因为您有一个静态ID,并且只想检索一个内容控件,所以只需直接寻址它,而不需要lamdas、集合或其他任何东西:
doc.ContentControls[gcc_ID]

从本机内容控件中,可以添加类型为GroupContentControl的VSTO内容控件。此对象是动态的,一旦外接程序超出范围,将不会保留在文档(或其他任何地方)中

从现在开始,你应该没事了

    private void btnGroupCC_Click(object sender, RibbonControlEventArgs e)
    {
        Word.Document doc = Globals.ThisAddIn.Application.ActiveDocument;
        // Get a VSTO document object
        Microsoft.Office.Tools.Word.Document VSTOdoc = Microsoft.Office.Tools.Word.Extensions.DocumentExtensions.GetVstoObject(doc);
        // Find the GCC in the document, by its ID
        string gcc_ID = "778611894";
        Word.ContentControl cc = doc.ContentControls[gcc_ID];
        Microsoft.Office.Tools.Word.GroupContentControl gcc = VSTOdoc.Controls.AddGroupContentControl(cc, "groupCC");
        // Safety check
        if (gcc == null)
            MessageBox.Show("no group cc");

        // Delete the GCC

        gcc.Delete(false);
    }

参考:,关于在运行时添加内容控件的主题。

非常有趣。我是Office外接程序编程新手(这是我第一次),所以我可能不会使用正确的词语:我真正需要的是创建和删除GroupContentControl,我只使用术语“VSTO”来指代我正在编程的外接程序的类型。换句话说,如果本机对象可以工作,我不需要使用VSTO对象。我还不熟悉C#和.NET,所以我不明白为什么我获取VSTO文档对象的方法与您的不同。您正在将其分配给一个中间变量(“doc”),我没有,但我不知道它有什么区别。我在您的答案中尝试了代码,它似乎可以工作,因为以前锁定的段落可以再次编辑。但是如果我尝试再次锁定该段落,通过创建一个同名的新GroupContentControl,我会得到以下异常:Microsoft.Office.Tools.ControlNameReadyExistException:'无法添加该控件,因为名为“Group_CC”的控件控件集合中已经存在。因此我不知道GCC是否真的被删除了……进一步的实验表明,如果我删除GroupContentControl,然后保存文档并退出Word,然后重新打开这两个控件,我可以添加一个与我删除的控件同名的新GroupContentControl。但是,如果我尝试在同一Word会话中删除/添加“cycle”,我将得到异常“name ready exists”。我知道ContentControl名称仅在运行时使用,而不保存在文档本身中,因此删除内容控件似乎只会从文档中删除它,它的名称仍然存在于Word中。我想这可能与Word的“撤消”堆栈有关,对吗?我终于找到了一个解决方案,可以满足我的需要:我只需在任何时候添加GroupContentControl时使用DateTime.Now和一个随机数生成一个唯一的名称。我只存储GCC的ID,并在需要删除它时使用它再次查找它。我将很快用相关代码回答我自己的问题。你的困惑源于你没有深入阅读VSTO文档,甚至没有阅读我给你的参考链接。VSTO扩展了本机Word对象的功能:您可以执行“interop”一词提供的所有操作,还可以执行其他一些操作。VSTO“包装”本机控件以提供扩展。在本例中,它创建了一个围绕本机对象的“虚拟”VSTO对象。此信息在运行时被缓存,因此不能重复使用该名称。当VSTO外接程序超出范围时,它将丢失,这就是为什么该名称稍后会再次工作的原因。