为什么 VSTO Word ContentControl 没有 Name 属性?

发布于 2024-10-18 06:31:50 字数 1657 浏览 5 评论 0原文

当您添加 VSTO(不是 Word 本机) 内容控制,指定名称:

controls.AddContentControl(wordRange, "foo", wdType);

其中,controls 是 VSTO(扩展)Document.Controls 集合。

您稍后可以按名称查找该控件:

ContentControl myContentControl = controls["foo"];

那么为什么 ContentControl 没有 Name 属性呢? (或 ContentControlBase,或任何其他衍生物)。

我正在为 Document.Controls 属性实现一个包装类,它允许您添加或迭代内容控件。当迭代底层 Document.Controls 时,无法查找每个控件的名称。 (我们需要它来返回 ContentControl 包装器的实例)。因此,目前我正在 ContentControls 包装类中执行此操作:

    public IEnumerator<IContentControl> GetEnumerator()
    {
        System.Collections.IEnumerator en = this.wordControls.GetEnumerator();
        while (en.MoveNext())
        {
            // VSTO Document.Controls includes all managed controls, not just 
            // VSTO ContentControls; return only those.
            if (en.Current is Microsoft.Office.Tools.Word.ContentControl)
            {
                // The control's name isn't stored with the control, only when it was added,
                // so use a placeholder name for the wrapper.
                yield return new ContentControl("Unknown", (Microsoft.Office.Tools.Word.ContentControl)en.Current);
            }
        }
    }

我不想在 ContentControls 对象中保留名称到包装对象的映射。谁能告诉我如何获取控件的名称(传递给 Controls.Add() 的名称参数?

When you add a VSTO (not Word native) content control, you specify the name:

controls.AddContentControl(wordRange, "foo", wdType);

Where controls is the VSTO (extended) Document.Controls collection.

You can later look up the control by name:

ContentControl myContentControl = controls["foo"];

So why in the world is there no Name property for ContentControl? (or ContentControlBase, or any of the other derivatives).

I'm implementing a wrapper class for the Document.Controls property that lets you add or iterate the content controls. When iterating the underlying Document.Controls, there's no way to look up the name of each control. (We need it to return an instance of our ContentControl wrapper). So currently I'm doing this in our ContentControls wrapper class:

    public IEnumerator<IContentControl> GetEnumerator()
    {
        System.Collections.IEnumerator en = this.wordControls.GetEnumerator();
        while (en.MoveNext())
        {
            // VSTO Document.Controls includes all managed controls, not just 
            // VSTO ContentControls; return only those.
            if (en.Current is Microsoft.Office.Tools.Word.ContentControl)
            {
                // The control's name isn't stored with the control, only when it was added,
                // so use a placeholder name for the wrapper.
                yield return new ContentControl("Unknown", (Microsoft.Office.Tools.Word.ContentControl)en.Current);
            }
        }
    }

I'd prefer to not have to resort to keeping a map of names-to-wrapper-objects in our ContentControls object. Can anyone tell me how to get the control's name (the name parameter that was passed to Controls.Add()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

断念 2024-10-25 06:31:50

当您以编程方式添加 CC,然后需要在同一 Word 实例期间立即访问它时,“名称”参数纯粹是为了便于操作。对 CC 的事后访问是通​​过 ContentControl.ID 属性中的 GUID 进行的。因此,从这个意义上说,“名称”对于以后的访问和操作来说相当无用,因为它没有保留在 WordprocessingML 标记中。

一种更简单的处理方法是忽略“名称”指定,添加一个 CC,获取它的 .ID 然后使用它。诚然,Guid 对于人类读者来说毫无意义,但您的程序应该能够解释它。

如果您确实需要通过有意义的名称(例如“foo”)获取 CC,只需使用 .Tag 属性作为您的 CC 名称(它只需要对每个 CC 来说是唯一的,但对于您的 CC 来说)标签作为名称)并通过标签查询 ContentControlCollection。

The "name" argument is purely for ease of manipulation when you are programmatically adding a CC and then needing immediate access to it during the same instance of Word. After-the-fact access to a CC is by way of a GUID in the ContentControl.ID property. So in that sense, "name" is fairly useless for later access and manipulation as it is not retained in the WordprocessingML markup.

An easier way of approaching it is to just ignore the "name" designation all together, add a CC, grab it's .ID and then use that. Granted, the Guid is fairly meaningless to a human reader, but your program should be able to account for it.

If you really do need to grab a CC by a meaningful name, such as "foo", just use the .Tag property for your CC's name (it just needs to be unique for each CC though for your tags to work as names) and query the the ContentControlCollection by tags.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文