- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在为 excel 创建一个 VSTO Ribbon AddIn,我正在我的应用程序中存储一些工作簿状态信息,我用它来更新启用的可视按钮。考虑到可以有多个工作簿,我将这个状态对象存储在 ThisAddIn 类的字典中。我的问题是我不知道如何为工作簿获取唯一的 Hash/Key/Guid,因为我得到的只是一个不断更改哈希的 COM 包装器。很公平,我完全理解这一点。
我使用了很长时间的一个解决方案是创建一个 guid 并将其存储在工作簿的 CustomDocumentProperties 中,并根据它作为键来映射状态。这至少有效,但如果我创建工作簿的副本并在同一个应用程序实例中打开它并且现在有多个具有相同 guid 的工作簿,它就会失败。
我现在有一个想法,我想我可以在 Workbook_Open 事件上刷新这个 Guid。但这仍然是一个不可靠的解决方案。
我在这里找到的第二个解决方案: http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/04efa74d-83bd-434d-ab07-36742fd8410e/
所以我使用了那些人的代码并创建了这个:
public static class WorkbookExtensions
{
public static IntPtr GetHashery(this msExcel.Workbook workbook)
{
IntPtr punk = IntPtr.Zero;
try
{
punk = Marshal.GetIUnknownForObject(workbook);
return punk;
}
finally
{
//Release to decrease ref count
Marshal.Release(punk);
}
}
}
它在几分钟内运行良好,直到在访问 Application.ActiveWorkbook 时开始出现臭名昭著的错误“无法使用与其底层 RCW 分离的 COM 对象”。
这是引用 Workbook COM 对象的安全方法吗?如果我有两个功能区应用程序都使用此方法来获取单个工作簿 GUID 怎么办?如果其中一个应用程序在我的状态对象上运行垃圾收集器,它会调用终结器来调用 Marshal.FinalReleaseComObject(workbook) 怎么办?有什么方法可以获得工作簿的引用计数,这样我就不会在其他功能区应用程序完成它们之前调用 FinalRelease 吗?清理 VSTO 中的 Workbook COM 对象以保持与这些其他应用公平竞争的一些最佳做法是什么?
当然,我不是第一个想要根据工作簿状态启用按钮的人,其他人是怎么做到的?我在此处查看了 Stack Overflow 上的其他几篇文章,但没有一篇对我使用 Workbook Guid 解决方案有很大帮助。
我正在使用 Ribbon Designer,并连接到 Workbook Load 和 Deactivate 事件。
提前致谢,希望我已经提供了所有详细信息。
最佳答案
我最终通过简单地将 IntPtr 转换为 long 来解决这个问题,然后 IntPtr 的处置不会影响我。我不需要保留 IntPtr,因为我真正需要的只是工作簿的一些独特之处。
以下代码允许我存储特定于工作簿的状态信息,因此我可以根据自定义对象工作簿状态更新功能区中按钮的视觉状态。您可以在自定义 WorkbookState 类中存储您想要的任何信息,但通常是您不想保留在电子表格本身中的特定于 session 的信息。
单独的工作簿扩展:
public static class WorkbookExtensions
{
public static long GetHashery(this msExcel.Workbook workbook)
{
if (workbook == null)
{
throw new ArgumentNullException("workbook");
}
IntPtr pUnknown = IntPtr.Zero;
try
{
pUnknown = Marshal.GetIUnknownForObject(workbook);
return pUnknown.ToInt64();
}
finally
{
// GetIUnknownForObject causes AddRef.
if (pUnknown != IntPtr.Zero)
{
Marshal.Release(pUnknown);
}
}
}
}
然后在我的 VSTO/ExcelDna ThisAddIn 类中,我使用上述方法存储所有工作簿状态的映射以查找唯一的工作簿哈希键:
private Dictionary<long, WorkbookState> _workbookStates = new Dictionary<long, WorkbookState>();
public WorkbookState WorkbookState
{
get
{
long hash = Application.ActiveWorkbook.GetHashery();
WorkbookState state;
if (!_workbookStates.TryGetValue(hash, out state))
{
state = _workbookStates[hash] = new WorkbookState();
}
return state;
}
}
当然,现在我可以通过简单地调用 ThisAddIn.WorkbookState
关于c# - 在 VSTO 中获取 Excel 工作簿的哈希码以启用基于状态的按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15940358/
我想知道如何首先检测 Javascript 是否启用/禁用。在此站点上禁用 javascript 表明 stackoverflow 使用了称为标签的东西。 这是标准的做法吗?它适用于所有浏览器吗?它不
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How to enable PHP short tags ? Enable short open tags
在 VSTS (Azure DevOps) 上拥有私有(private)存储库我尝试通过将以下内容添加到 .csproj 文件来启用 SourceLink:https://github.com/dot
我创建了一个 wx.Frame(我们称之为 mainFrame)。该框架上包含一个按钮,当单击该按钮时,会创建一个新框架(我们称之为 childFrame)。 我想知道如何在创建 childFrame
当我禁用 WPF 中的控件时,比如说一个菜单项 MenuItem aMenuItem = ... aMenuItem.IsEnabled = false; MenuItem 中的文本仍然处于事件状态,
我想在我的 nginx 服务器上启用 gzip 压缩。 nginx.conf 文件在这里: http { # Enable Gzip server { location ~* \.(?
我正在使用免费的 heroku 附加 PG 备份并遵循这些 instructions .我找到了安装应用程序的命令:heroku addons:add pgbackups:auto-week。但是我想
我想知道脚本是否可以使用某种切换按钮启用/禁用页面上的所有输入元素。 我用谷歌搜索了它,但除了这个之外没有发现任何有用的东西: http://www.codetoad.com/javascript/e
在我的 php 文件中,我想使用 jQuery Datepicker。 当我的文件加载时,我创建了禁用的日期选择器。 然后,当我的 php 文件(它是一个表单)中的一个特殊字段被填充时,我想启用日期选
我有一个按钮,如下所示: RadButton lnkAdd = new RadButton(); lnkAdd.ID = "BtnAdd"; lnkAdd.CommandName = RadGrid.
public static void ToggleTaskManager(string keyValue) { RegistryKey objRegistryK
我正在 Azure 中使用事件网格订阅,该订阅在创建 Blob 时触发。然而,我们有很多文件进入这个 blob,比如说 1000 多个。 如果我发现任何文件有任何错误,我想做的是禁用事件订阅。 最佳答
我的网站上有几个使用 HTML5 contentEditable 属性的 div。目标是让用户能够开始编写日记条目,并将保存按钮从禁用更改为启用。 这是我目前拥有的 HTML: Write
我有一个范围输入,其定义如下: @Html.LabelFor(m => Model.Quality, Resources.CompressionQuality) 和一个下拉菜单: @Html.Lab
我正在尝试创建一个启用/禁用按钮的下拉菜单,并且我正在关注此 example 但它已经有 4 年历史了,而且该功能似乎无法在我的 xhtml 页面上运行。 任何帮助都将被适当 最佳答案 这是一个现场演
我正在 Azure 中使用事件网格订阅,该订阅在创建 Blob 时触发。然而,我们有很多文件进入这个 blob,比如说 1000 多个。 如果我发现任何文件有任何错误,我想做的是禁用事件订阅。 最佳答
我在这里遇到一个非常奇怪的情况:我编写了一个应用程序,除其他外,将连接的代理从打开切换到关闭,反之亦然。通过更改注册表中的值来完成此操作: public void SetUpProxy(string
我需要调整一堆 PVC 的大小。似乎最简单的方法是通过ExpandPersistentVolumes 功能。但是我无法获得配置合作。 ExpandPersistentVolumes feature g
如果我的TextField为空,则应禁用该按钮,并且该按钮的textColor和borderColor应该为灰色。但是,启用按钮后,颜色应为蓝色。 更改textColor很容易: button.Set
您好,我的问题是:我无法从另一个类启用表单的按钮。我的表单类是 public class FileSending { //Function for enabling the button
我是一名优秀的程序员,十分优秀!