VSTO Excel:重新打开文件时恢复 ListObject 数据源

发布于 2024-12-15 18:45:00 字数 1803 浏览 6 评论 0原文

我正在开发 Excel 2010 模板项目。在我的模板中,我有许多工作表,每个工作表中都包含静态 ListObject 控件。为了初始化我的 ListObject,我绑定了 BindingList,以便它为我的每个 MyCustomType 公共属性生成一列。它真的很方便,因为当用户使用 ListObject 中的某些行时,它会自动填充我的 BindingList 实例。我在 Excel 功能区中添加了一个按钮,以便程序可以通过 EDM 验证并提交这些行。这就是我将数据绑定到 Excel 工作表之一的启动事件处理程序中的 ListObject 的方法。

public partial class MyCustomTypesSheet
{
    private BindingList<MyCustomType> myCustomTypes;

    private void OnStartup(object sender, System.EventArgs e)
    {
        ExcelTools.ListObject myCustomTypeTable = this.MyCustomTypeData;
        BindingList<MyCustomType> customTypes = new BindingList<MyCustomType>();

        myCustomTypeTable.SetDataBinding(customTypes);
    }

    // Implementation detail...
}

现在我的问题是,该模板的用户很可能会在许多会话中输入这些行。这意味着他将输入数据、保存文件、关闭文件、重新打开文件、输入一些新行,并最终在他认为完成时尝试提交这些行。我注意到,当重新打开从模板创建的 Excel 文件时,ListObject 控件的 DataSource 属性为 null。这意味着我无法将 ListObject 中的数据返回到 BindingList 中。我一直在搜索,但没有找到自动执行此操作的方法,而且我真的不想编写一段代码来爬行所有列来重新创建我的 MyCustomType 实例。在理想的世界里我会这样做。

private void OnStartup(object sender, System.EventArgs e)
{
    ExcelTools.ListObject myCustomTypeTable = this.MyCustomTypeData;
    BindingList<MyCustomType> customTypes = null;

    if (myCustomTypeTable.DataSource == null) // Will always be null and erase previous data.
    {
        customTypes = new BindingList<MyCustomType>();
        myCustomTypeTable.SetDataBinding(customTypes);
    }
    else
    {
        customTypes = myCustomTypeTable.DataSource as BindingList<MyCustomType>;
    }
}

我对此做了很多研究,但找不到解决方案,所以我希望你们中的一些人可以帮助我解决这个问题。

谢谢。

I am working on an Excel 2010 template project. In my template I have many sheets with static ListObject controls in each of them. To initialize my ListObject, I bind a BindingList<MyCustomType> so it generates a column for each of my MyCustomType public properties. It is really handy because when the user some rows in the ListObject, it automatically fills up my BindingList instance. I added a button in the Excel ribbon so that the program can validate and commit these rows through an EDM. This is how I bind my data to the ListObject in the startup event handler of one of my Excel sheet.

public partial class MyCustomTypesSheet
{
    private BindingList<MyCustomType> myCustomTypes;

    private void OnStartup(object sender, System.EventArgs e)
    {
        ExcelTools.ListObject myCustomTypeTable = this.MyCustomTypeData;
        BindingList<MyCustomType> customTypes = new BindingList<MyCustomType>();

        myCustomTypeTable.SetDataBinding(customTypes);
    }

    // Implementation detail...
}

Now my issue is that it is very likely that the user of this template will enter these rows in many sessions. It means that he will enter data, save the file, close it, reopen it, enter some new rows and eventually try to commit these rows when he thinks he is done. What I noticed is that when the Excel file created from the template is reopened, the DataSource property of my ListObject controls is null. Which means I have no way to get back the data from the ListObject into a BindingList<MyCustomType>. I have been searching and I found no automatic way to do that and I don't really want to make a piece of code that would crawl through all of the columns to recreate my MyCustomType instances. In an ideal world I would have done like this.

private void OnStartup(object sender, System.EventArgs e)
{
    ExcelTools.ListObject myCustomTypeTable = this.MyCustomTypeData;
    BindingList<MyCustomType> customTypes = null;

    if (myCustomTypeTable.DataSource == null) // Will always be null and erase previous data.
    {
        customTypes = new BindingList<MyCustomType>();
        myCustomTypeTable.SetDataBinding(customTypes);
    }
    else
    {
        customTypes = myCustomTypeTable.DataSource as BindingList<MyCustomType>;
    }
}

I have been doing a lot of research on this but I was not able to find a solution so I hope some of your can help me to resolve this issue.

Thanks.

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

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

发布评论

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

评论(1

葬花如无物 2024-12-22 18:45:00

作为最后一个解决方案,我决定用 XML 序列化我的对象列表,然后在保存时将其作为 XML 自定义部分添加到我的 Excel 文件中。但是当我查阅 MSDN 文档来实现这一点时,我发现有两种方法来保存数据:XML 自定义部分和数据缓存。实际上数据缓存正是我正在寻找的功能。

因此,我只需使用 CachedAttribute 就可以实现我的目标。

public partial class MyCustomTypesSheet
{
    [Cached]
    public BindingList<MyCustomType> MyCustomTypesDataSource { get; set; }

    private void OnStartup(object sender, System.EventArgs e)
    {
        ExcelTools.ListObject myCustomTypeTable = this.MyCustomTypeData;

        if (this.MyCustomTypesDataSource == null)
        {
            this.MyCustomTypesDataSource = new BindingList<MyCustomType>();
            this.MyCustomTypesDataSource.Add(new MyCustomType());
        }

        myCustomTypeTable.SetDataBinding(this.MyCustomTypesDataSource);
    }

    private void InternalStartup()
    {
        this.Startup += new System.EventHandler(OnStartup);
    }
}

它就像一个魅力。您可以在 MSDN 文档中找到有关数据缓存的更多信息。

As a last solution I decided that I would serialize my object list in XML and then add it as a XML custom part to my Excel file on save. But when I got into MSDN documentation to achieve this, I found out that there was 2 ways to persist data: XML custom part and data caching. And actually data caching was exactly the functionality I was looking for.

So I have been able to achieve my goal by simply using the CachedAttribute.

public partial class MyCustomTypesSheet
{
    [Cached]
    public BindingList<MyCustomType> MyCustomTypesDataSource { get; set; }

    private void OnStartup(object sender, System.EventArgs e)
    {
        ExcelTools.ListObject myCustomTypeTable = this.MyCustomTypeData;

        if (this.MyCustomTypesDataSource == null)
        {
            this.MyCustomTypesDataSource = new BindingList<MyCustomType>();
            this.MyCustomTypesDataSource.Add(new MyCustomType());
        }

        myCustomTypeTable.SetDataBinding(this.MyCustomTypesDataSource);
    }

    private void InternalStartup()
    {
        this.Startup += new System.EventHandler(OnStartup);
    }
}

It works like a charm. You can find more information about data caching in MSDN documentation.

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