泛型类型:没有从 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,但这不起作用,因为它没有invoke方法。

结果:在重新审视我的解决方案后,我按照 Jimmy 最初的建议将其实现为扩展方法。

我创建了一个静态的ExtensionMethod类(在它自己的"ExtensionMethods"命名空间中),添加到InvokeOnToolStripItem方法中,在我的原始类中添加了一个"using ExtensionMethods;"指令,并按如下方式调用这些方法:

tsStatusValue.InvokeOnToolStripItem(ts => ts.Text = "ALARM signal received");

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());

为了解释错误消息,您已经写了

where t : Control

但 ToolStripStatusLabel 不会继承自 Control。

不确定这是否对您有所帮助,并且还没有真正的解决方案:(

最新更新