开发者

Generic Types: There is no implicit reference conversion from ToolStripStatusLabel to Control

开发者 https://www.devze.com 2023-03-05 04:36 出处:网络
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 si

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<开发者_StackOverflow中文版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");


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


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 :(

0

精彩评论

暂无评论...
验证码 换一张
取 消