通用类型:不存在从 ToolStripStatusLabel 到 Control 的隐式引用转换

发布于 2024-11-06 19:03:14 字数 1305 浏览 7 评论 0原文

我想从 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,但这不起作用,因为它没有调用方法。

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

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

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

I'm wanting to update the UI from a SerialPort DataReceived event handler. I discovered a problem because the event handler was implicitly running in a different thread to the form, so rather than simply update the UI...

myLabel.Text = "Some text";

...I had to take the following approach:

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

So far so good... However, now I want to update a ToolStripStatusLabel - using the same approach yields a 'there is no implicit reference conversion between ToolStripStatusLabel and Forms.Control' error.

From what I have read, the problems stems from the fact that you can't Invoke a ToolStripStatusLabel.

So how best do I handle this?

Note: delegates, etc are at the threshold of my current ability, so an explanation alongside a solution would be appreciated.

UPDATE 1: Just to clarify, I tried to create ToolStripStatusLabel equivalent of InvokeControlAction, but this won't work because it doesn't have an invoke method.

RESULT: After revisiting my solution, I've implemented it as an Extension Method as Jimmy originally suggested.

I created an static ExtensionMethod class (in it's own 'ExtensionMethods' namespace), added in the InvokeOnToolStripItem method, add a 'using ExtensionMethods;' directive in my original class and called the methods as follows:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴情换悲伤 2024-11-13 19:03:14

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

ToolStripStatusLabel does not inherit from Control, and that's why your generic constraint fails for the exact reason you posted.

What is more, ToolStripStatusLabel (or any ToolStripItem in fact) doesn't have Invoke method. Luckily, containing ToolStrip has, which can be easily accessed using GetCurrentParent method.

Here's extension method that works on any 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);
    }
}

You can use it by simply calling:

myToolStripLabel.InvokeOnToolStripItem(label => label.Text = "Updated!");
myToolStripProgressBar.InvokeOnToolStripItem(bar => bar.PerformStep());
天赋异禀 2024-11-13 19:03:14

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

where t : Control

但 ToolStripStatusLabel 不继承自 Control。

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

To explain the error message, you have writen

where t : Control

but ToolStripStatusLabel does not inherit from Control.

Not sure if that helps you at all and don't really have a solution yet :(

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文