在.NET Excel插件中设置剪贴板中的自定义数据

时间:2010-08-30 02:49:26

标签: c# .net clipboard add-in

我有一个用C#编写的Excel插件,它有一些复制/粘贴处理代码。当用户复制时,我想将自己的TableData类对象放在剪贴板上,并在用户将数据粘贴到工作表上时将其检索回来。听起来很简单,我在网上发现了十几篇文章,但由于某些原因,我的代码无效。

这是我的TableData类:

[Serializable]
[Guid("794E06D9-7CE4-40dc-8187-BDC105A0F866")]
public class TableData
{
    public string Name;

    public TableData()
    { }
}

我甚至给它一个GUID,以确保它加载完全相同的类,即使它是从其他程序集加载(如果addin对象由于某种原因加载了两次)。

这是我在复制时设置数据的方法:

TableData data = new TableData();
data.Name = "test";
Clipboard.SetData("MyTable", data);

在粘贴:

TableData data = Clipboard.GetData("MyTable") as TableData;

HERE>> data为null但是如果我在即时窗口中打印GetData(“MyTable”),它会显示 一个内存流,即使使用BinaryFormatter :: DeSerialize()方法也无法转换为TableData

我可能在这里犯了一些愚蠢的错误,但我无法弄明白。有人可以在这里指出问题吗?

已更新

它是一个COM插件而不是VSTO插件。我已经在OnKey方法中设置了宏,因此当用户在Excel工作表中按下CTRL + C和CTRL + V时会调用它们。有一个单独的VBA模块可以处理这些请求并将它们路由到.NET插件。

Application.OnKey("^c", "OnCopy");

所以调用转到VBA,然后VBA回调到我的.NET插件。不确定调用之间是否还涉及其他进程。

如果我从剪贴板中放入并检索byte []而不是我的自定义类

,则工作正常

3 个答案:

答案 0 :(得分:1)

疑难杂症!!

问题是代码在粘贴期间无法找到相同的类型。这是因为插件位于与主机应用程序不同的位置,即Excel。 我尝试通过序列化类然后将其放在剪贴板上。然后将其序列化为原始类型,但在De-Serialize期间失败并且“抛出了TargetInvocationException *”,说“无法找到程序集 [addin程序集全名] ”。剪贴板:: SetData( ...)没有抛出任何异常,只是默默地处理它并返回NULL。

解决方案是处理 AppDomain.CurrentDomain.AssemblyResolve 事件,并在查询addin程序集时返回当前正在执行的程序集。

答案 1 :(得分:0)

我使用上面的确切代码创建了一个带有复制和粘贴按钮的简单VSTO插件。 Table对象在Paste hander中正确可用。

  1. 如何在插件中启动粘贴?从Excel事件,还是从插件中的用户操作?
  2. 这是使用任务窗格的VSTO插件吗?请详细说明。
  3. 粘贴是否发生在Excel的其他流程实例中?

答案 2 :(得分:0)

article列出了一些可能有用的步骤。这些包括注册剪贴板格式,显式创建DataObject并将其数据设置为TableData,然后将剪贴板数据设置为DataObject。它值得一试,因为它只有几行代码。