我想从SerialPort DataReceived事件处理程序更新UI。我发现了一个问题,因为事件处理程序隐式运行在与表单不同的线程中,所以不是简单地更新UI ...
myLabel.Text = "Some text";
......我必须采取以下方法:
InvokeControlAction<Label>(myLabel, lbl=> lbl.Text= "Some text");
...
public static void InvokeControlAction<t>(t cont, Action<t> action) where t : Control
{
if (cont.InvokeRequired)
{
cont.Invoke(new Action<t, Action<t>>(InvokeControlAction),
new object[] { cont, action });
}
else
{
action(cont);
}
}
到目前为止一切都很好......但是,现在我想更新一个ToolStripStatusLabel - 使用相同的方法产生'在ToolStripStatusLabel和Forms.Control之间没有隐式引用转换'错误。
根据我的阅读,问题源于您无法调用ToolStripStatusLabel这一事实。
那我该如何处理呢?
注意:代表等处于当前能力的门槛,因此可以理解与解决方案一起解释。
更新1:为了澄清,我试图创建相当于InvokeControlAction的ToolStripStatusLabel,但这不起作用,因为它没有调用方法。
结果:重新访问我的解决方案后,我已将其实现为Jimmy最初建议的扩展方法。
我创建了一个静态 ExtensionMethod 类(在它自己的'ExtensionMethods'命名空间中),在InvokeOnToolStripItem方法中添加了一个'using ExtensionMethods;'我的原始类中的指令,并调用如下方法:
tsStatusValue.InvokeOnToolStripItem(ts => ts.Text = "ALARM signal received");
答案 0 :(得分:2)
ToolStripStatusLabel
不会从Control
继承,这就是您的通用约束因您发布的确切原因而失败的原因。
此外,ToolStripStatusLabel
(或任何ToolStripItem
实际上)没有Invoke
方法。幸运的是,包含ToolStrip
,可以使用GetCurrentParent
方法轻松访问。
这是适用于任何ToolStripItem
的扩展方法:
public static void InvokeOnToolStripItem<T>(this T item, Action<T> action)
where T : ToolStripItem
{
ToolStrip parent = item.GetCurrentParent();
if (parent.InvokeRequired)
{
parent.Invoke((Delegate)action, new object[] { item });
}
else
{
action(item);
}
}
您只需致电:
即可使用它myToolStripLabel.InvokeOnToolStripItem(label => label.Text = "Updated!");
myToolStripProgressBar.InvokeOnToolStripItem(bar => bar.PerformStep());
答案 1 :(得分:0)
要解释错误消息,您已写入
where t : Control
但ToolStripStatusLabel不从Control继承。
不确定这对你有什么帮助,还没有真正的解决方案:(