c# - 通用类型 : There is no implicit reference conversion from ToolStripStatusLabel to Control

标签 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。

那么我该如何最好地处理这个问题呢?

注意:委托(delegate)等处于我当前能力的阈值,因此将不胜感激与解决方案一起解释。

更新 1: 澄清一下,我尝试创建与 InvokeControlAction 等效的 ToolStripStatusLabel,但这行不通,因为它没有调用方法。

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

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

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

最佳答案

<a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripstatuslabel.aspx" rel="noreferrer noopener nofollow">ToolStripStatusLabel</a>不继承自 Control ,这就是您的通用约束因您发布的确切原因而失败的原因。

此外,ToolStripStatusLabel (或任何 ToolStripItem 事实上)没有 Invoke方法。幸运的是,包含 ToolStrip有,可以使用 <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripitem.getcurrentparent.aspx" rel="noreferrer noopener nofollow">GetCurrentParent</a> 轻松访问方法。

这是适用于任何 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());

关于c# - 通用类型 : There is no implicit reference conversion from ToolStripStatusLabel to Control,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5979233/

相关文章:

c# - 尝试使用 iTextSharp 添加 PDF 图章, "The byte array is not a recognized imageformat"

c# - C# 中的触发事件会阻止当前线程执行吗?

objective-c - AppDelegate 可能无法响应 'delegate'

ios - 如何修复条件绑定(bind)的可选类型不是 'Bool'?

c# - 调用卡住我的 Windows 窗体

java - 事件派发线程如何工作?

c# - Invoke方法如何实现?

c# - 正则表达式 : .net 与 javascript 中特殊字符的差异

c# - Fluent Api Entity Framework 核心

c# - LambdaExpression.Compile 和 Delegate.CreateDelegate 之间的区别