Excel VSTO C#-创建列表对象';VSTO对应项中断重命名

Excel VSTO C#-创建列表对象';VSTO对应项中断重命名,c#,excel,vsto,add-in,office-addins,C#,Excel,Vsto,Add In,Office Addins,我正在使用C#为Excel编写一个VSTO加载项,需要将元数据绑定到工作表中创建的表,这些表不能向用户公开,也不能在工作表中复制表时复制。为此,我正在使用它,它工作得很好,似乎是针对这个用例的。为了设置标记属性,我创建了列表对象的VSTO对象,因为该属性在interop对象中不可用: foreach(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets中的Microsoft.Office.Interop.Excel.Worksheet工作

我正在使用C#为Excel编写一个VSTO加载项,需要将元数据绑定到工作表中创建的表,这些表不能向用户公开,也不能在工作表中复制表时复制。为此,我正在使用它,它工作得很好,似乎是针对这个用例的。为了设置
标记
属性,我创建了
列表对象
的VSTO对象,因为该属性在interop对象中不可用:

foreach(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets中的Microsoft.Office.Interop.Excel.Worksheet工作表)
{
foreach(工作表中的Microsoft.Office.Interop.Excel.ListObject表。ListObjects)
{
Microsoft.Office.Tools.Excel.ListObject vstoTable=Globals.Factory.GetVstoObject(表);
vstoTable.Tag=newtag{Identifier=123};
}
}
但是,只要为
ListObject
创建VSTO对象,就不能再更改表的名称。我仍然可以在“表选项”UI中编辑它,但保存工作簿将自动将名称还原为创建VSTO对象时的名称。我试图处理VSTO对象,但没有结果。即使我没有设置
标记
,问题仍然存在,仅仅创建VSTO对象似乎就足以触发此问题。有趣的是,我还为工作表创建了VSTO对象对应项,并设置了它们的
标记
属性,但即使创建了对象并设置了标记,我仍然可以重命名它们

为了验证我的其他代码都不会影响此功能,我创建了一个新的外接程序项目,只将上面的代码片段放在功能区按钮上,并且出现了相同的问题。我还尝试使用interop中提供的其他几个属性来避免创建VSTO对象,但它们要么向用户公开,要么与表一起复制,要么两者兼而有之


很明显,我使用的对象不正确,或者这是Excel中的一个问题。是否有人知道如何设置
标记
而不丢失重命名表的功能,或者是否有其他方法可用于将元数据附加到表?

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

    /// <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);
    }
//
///通过按名称搜索本机列表对象来创建VSTO列表对象
///如果找到列表对象,它会将其强制转换为
///VSTO列出对象并将其从工作表中删除
///一旦删除(或未找到),它将创建一个VSTO列表对象
///并将其添加到工作表中
/// 
///要将列表对象添加到的工作表
///要重新创建的列表对象的名称
///VSTO列表对象
公共静态ExcelVSTO.ListObject重新创建VSTOListObject(此ExcelVSTO.Worksheet工作表,字符串名称)
{
Excel.ListObject ListObject=Globals.ThisAddIn.GetListObjectByName(工作表,名称);
if(listObject!=null)
{
Microsoft.Office.Tools.Excel.ListObject vstoListObject=Globals.Factory.GetVstoObject(ListObject);
工作表.控件.删除(名称);
}
返回worksheet.Controls.AddListObject(Globals.ThisAddIn.Application.Selection,name);
}

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

    /// <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);
    }
//
///通过按名称搜索本机列表对象来创建VSTO列表对象
///如果找到列表对象,它会将其强制转换为
///VSTO列出对象并将其从工作表中删除
///一旦删除(或未找到),它将创建一个VSTO列表对象
///并将其添加到工作表中
/// 
///要将列表对象添加到的工作表
///要重新创建的列表对象的名称
///VSTO列表对象
公共静态ExcelVSTO.ListObject重新创建VSTOListObject(此ExcelVSTO.Worksheet工作表,字符串名称)
{
Excel.ListObject ListObject=Globals.ThisAddIn.GetListObjectByName(工作表,名称);
if(listObject!=null)
{
Microsoft.Office.Tools.Excel.ListObject vstoListObject=Globals.Factory.GetVstoObject(ListObject);
工作表.控件.删除(名称);
}
返回worksheet.Controls.AddListObject(Globals.ThisAddIn.Application.Selection,name);
}

不幸的是,在我的情况下,这不起作用,因为删除控件会清除其内容,我需要保留这些内容。也没有Excel触发的重命名事件,因此我不知道何时重新创建
ListObject
。在
WorkbookBeforeSave
事件中,名称已重置。不幸的是,在我的情况下,这不起作用,因为删除控件会清除其内容,我需要保留该内容。也没有Excel触发的重命名事件,因此我不知道何时重新创建
ListObject
。在
WorkbookBeforeSave
事件中,名称已重置。。