调用 ToolStripMenuItem

13
我正在尝试找出是否有一种方法来调用ToolStrip菜单项。 例如,当返回结果时我调用一个Web服务(异步地),在回调方法中根据结果填充下拉列表项。
 ToolStripMenuItem.DropDownItems.Add(new ToolStripItemEx("start"));

但是我遇到了异常

跨线程操作无效:控件''被访问的线程与创建它的线程不同。

工具栏项没有关联的调用函数,是否有其他方法可以实现此功能?我尝试这样做的方式完全错误吗?任何意见都将有所帮助。

2个回答

25
你正在尝试执行需要在另一个线程中控制主线程的代码,你应该使用Invoke方法来调用它:
toolStrip.Invoke(() =>
{
    toolStrip.DropDownItems.Add(new ToolStripItemEx("start"));
});

当从与控件最初创建的线程不同的线程访问控件成员/方法时,您应该使用 control.Invoke 方法,它将在调用的委托中封送执行到主线程。

编辑:由于您正在使用的是 ToolStripMenuItem 而不是 ToolStrip,因此 ToolStripMenuItem 没有 Invoke 成员,所以您可以使用 " this.Invoke " 调用窗体或者 toolStrip 的父级 "ToolStrip" 来调用,示例如下:

toolStrip.GetCurrentParent().Invoke(() =>
{
    toolStrip.DropDownItems.Add(new ToolStripItemEx("start"));
});

如何调用ToolStripMenuItem?该控件没有调用方法? - Zain Ali
我猜他知道这个……只是找不到在哪里。 - Random Dev
如果你正在使用WPF,那么你需要使用Dispatcher.Invoke - Jalal Said
使用Windows表单进行工作。问题是ToolStripMenuItem没有Invoke方法。请自行尝试。 - Zain Ali
考虑使用MethodInvoker委托,而不是Action可能是值得的(https://dev59.com/CnM_5IYBdhLWcg3w6X5e) - Kresten
显示剩余2条评论

6

您正在尝试从一个线程而不是主线程访问菜单项,因此请尝试使用以下代码:

MethodInvoker method = delegate
{
    toolStrip.DropDownItems.Add(new ToolStripItemEx("start"));
};

if (ToolStripMenu.InvokeRequired)
{
    BeginInvoke(method);
}
else
{
    method.Invoke();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接