3

我想从 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 方法中添加,添加一个“使用 ExtensionMethods;” 在我的原始类中指令并调用方法如下:

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

2 回答 2

2

ToolStripStatusLabel不继承自Control,这就是您的通用约束因您发布的确切原因而失败的原因。

更重要的是,ToolStripStatusLabel(或ToolStripItem实际上)没有Invoke方法。幸运的是,包含ToolStriphas,可以使用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());
于 2011-05-12T14:23:57.523 回答
0

为了解释错误信息,你写了

where t : Control

但 ToolStripStatusLabel 不继承自 Control。

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

于 2011-05-12T14:32:07.910 回答