向CustomTaskPane添加UserControl时触发System.InvalidCastException异常求助
我尝试用以下代码将UserControl添加到Microsoft.Office.Tools.CustomTaskPane实例myCustomTaskPane中:
myUserControl = new IssueAddition(categoryList); myCustomTaskPane = this.CustomTaskPanes.Add(myUserControl, "问题报告窗格"); // 报错行 myCustomTaskPane.Visible = true;
运行时抛出如下异常:
类型为“System.InvalidCastException”的异常在Microsoft.Office.Tools.Common.Implementation.dll中发生,但未在用户代码中处理
附加信息:
无法将类型为“System.__ComObject”的COM对象强制转换为接口类型“Microsoft.VisualStudio.Tools.Office.Runtime.Interop.ICustomTaskPaneSite”。
此操作失败的原因是,对COM组件执行QueryInterface调用以获取IID为“{3CA8CD11-274A-41B6-A999-28562DAB3AA2}”的接口时,出现以下错误: 不支持此接口 (HRESULT异常: 0x80004002 (E_NOINTERFACE))。
不清楚引发System.InvalidCastException异常的原因。
编辑1:附上仍报相同错误的最新实现代码
我有一个继承自System.Windows.Forms.UserControl的独立类IssueAddition,代码如下:
public partial class IssueAddition : UserControl { public IssueAddition() { InitializeComponent(); } public IssueAddition(List<String> categories) { InitializeComponent(); foreach (string cat in categories) this.i_issue_category.Items.Add(cat); } public string IssueCategoryInputText { get { return (string)this.i_issue_category.SelectedItem; } set { this.i_issue_category.SelectedItem = this.i_issue_category.FindStringExact(value); } } public string MessageInputText { get { return this.i_error_message.Text; } set { this.i_error_message.Text = value; } } }
该类在ThisAddIn.cs中的使用方式如下:
声明部分
#region 实例变量 Outlook.Application m_Application; internal static List<Outlook.Explorer> m_Windows; // 跟踪的资源管理器窗口列表 internal static List<Outlook.Inspector> m_InspectorWindows; // 跟踪的检查器窗口列表 private IssueAddition myUserControl; // <--
调用部分
public async void 添加问题() { List<String> categoryList = new List<String>(); await Task.Run(() => { categoryList = dAO.loadCategoryAsync("all").GetAwaiter().GetResult(); if (categoryList == null) categoryList = new List<String>(); myUserControl = new IssueAddition(categoryList); Add add = new Add(添加自定义控件); Globals.ThisAddIn.myUserControl.Invoke(add); }); } delegate void Add(); private void 添加自定义控件() { Globals.ThisAddIn.CustomTaskPanes.Add(myUserControl, "测试").Visible = true; }
编辑2:尝试使用Invoke方法,但仍抛出相同异常
public async void 添加问题() { List<String> categoryList = new List<String>(); await Task.Run(() => { categoryList = dAO.loadCategoryAsync("all").GetAwaiter().GetResult(); if (categoryList == null) categoryList = new List<String>(); myUserControl = new IssueAddition(categoryList); if (!Dispatcher.CurrentDispatcher.CheckAccess()) Dispatcher.CurrentDispatcher.Invoke(new Action(() => { Globals.ThisAddIn.CustomTaskPanes.Add(myUserControl, "测试").Visible = true; })); else Dispatcher.CurrentDispatcher.Invoke(new Action(() => { Globals.ThisAddIn.CustomTaskPanes.Add(myUserControl, "测试").Visible = true; })); }); }
编辑3:附上修改后可正常运行的代码
在ThisAddIn.cs中添加Dispatcher类型的实例变量_dispatcher;
在ThisAddIn_Startup方法中初始化:
private void ThisAddIn_Startup(object sender, System.EventArgs e) { _dispatcher = Dispatcher.CurrentDispatcher; }
调用方式修改为:
public async void 添加问题() { List<String> categoryList = new List<String>(); await Task.Run(() => { categoryList = dAO.loadCategoryAsync("all").GetAwaiter().GetResult(); if (categoryList == null) categoryList = new List<String>(); myUserControl = new IssueAddition(categoryList); _dispatcher.Invoke(new Action(() => { Globals.ThisAddIn.CustomTaskPanes.Add(myUserControl, "测试").Visible = true; })); }); }
内容的提问来源于stack exchange,提问作者Akanksha_p

