【问题标题】:Excel VSTO C# - Creating a ListObject's VSTO counterpart breaks renamingExcel VSTO C# - 创建 ListObject 的 VSTO 对应项会中断重命名
【发布时间】:2020-09-09 11:39:53
【问题描述】:

我正在使用 C# 为 Excel 编写 VSTO 加载项,并且需要将元数据绑定到工作表中创建的表,当表在工作表中复制时,这些表无法向用户公开或复制。为此,我使用了ListObject's Tag property,它运行良好,似乎适用于这个用例。为了设置Tag 属性,我创建了ListObject 的VSTO 对象,因为该属性在互操作对象中不可用:

foreach (Microsoft.Office.Interop.Excel.Worksheet worksheet in Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets)
{
    foreach (Microsoft.Office.Interop.Excel.ListObject table in worksheet.ListObjects)
    {
        Microsoft.Office.Tools.Excel.ListObject vstoTable = Globals.Factory.GetVstoObject(table);
        vstoTable.Tag = new Tag { Identifier = 123 };
    }
}

但是,一旦我为 ListObject 创建了 VSTO 对象,我就不能再更改表的名称。我仍然可以在表格选项 UI 中对其进行编辑,但保存工作簿会自动将名称恢复为创建 VSTO 对象时的名称。我尝试处理 VSTO 对象无济于事。即使我没有设置Tag,问题仍然存在,只需创建 VSTO 对象似乎就足以触发此问题。有趣的是,我还在为工作表创建对应的 VSTO 对象并设置它们的 Tag 属性,但即使在创建对象并设置标签之后,我仍然可以重命名它们。

为了验证我的其他代码都不会影响这一点,我创建了一个新的加载项项目,仅将上述代码 sn-p 放在功能区按钮上,并且发生了同样的问题。我还尝试使用互操作中可用的其他几个属性来避免创建 VSTO 对象,但它们要么都暴露给用户,要么与表一起被复制,要么两者兼而有之。

很明显,我要么错误地使用了这些对象,要么这是 Excel 中的一个问题。有谁知道我如何设置 Tag 而不会失去重命名表的能力,或者是否有任何其他方法可以用来将元数据附加到表?

【问题讨论】:

    标签: c# excel vsto add-in office-addins


    【解决方案1】:

    您可能想尝试删除并重新创建列表对象,每次使用您想要的名称,就像此扩展方法显示的那样。这在您的解决方案中可能不起作用,或者您可能必须修改参数以创建具有“新”名称的旧列表对象。每次重新创建列表对象时,我都会对其进行数据绑定,因此这适用于我的情况。

        /// <summary>
        /// Creates a VSTO list object by searching for a native list object by name
        /// If the list object is found it will cast it to a 
        /// VSTO list object and remove it from the worksheet
        /// Once removed (or not found) it will create a VSTO list object
        /// and add it to the worksheet
        /// </summary>
        /// <param name="worksheet"> The worksheet to add the list object to</param>
        /// <param name="name"> The name of the list object to re-create </param>
        /// <returns> The VSTO list object </returns>
        public static ExcelVSTO.ListObject RecreateVSTOListObject(this ExcelVSTO.Worksheet worksheet, string name)
        {
            Excel.ListObject listObject = Globals.ThisAddIn.GetListObjectByName(worksheet, name);
    
            if (listObject != null)
            {
                Microsoft.Office.Tools.Excel.ListObject vstoListObject = Globals.Factory.GetVstoObject(listObject);
                worksheet.Controls.Remove(name);
            }
    
            return worksheet.Controls.AddListObject(Globals.ThisAddIn.Application.Selection, name);
        }
    

    【讨论】:

    • 不幸的是,这在我的情况下不起作用,因为删除控件会清除其内容,我需要保留这些内容。也没有由 Excel 触发的重命名事件,所以我不知道何时重新创建 ListObject。在WorkbookBeforeSave 事件中,名称已被重置..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多