通用类型:没有从ToolStripStatusLabel到Control的隐式引用转换

时间:2011-05-12 14:05:19

标签: c# delegates invoke multithreading toolstripstatuslabel

我想从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");

2 个答案:

答案 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继承。

不确定这对你有什么帮助,还没有真正的解决方案:(