Click here to Skip to main content
Click here to Skip to main content
Go to top

A thread-safe ToolStripStatusLabel control

, 6 Jul 2007
Rate this:
Please Sign up or sign in to vote.
This article demonstrates how to extend a ToolStripStatusLabel so that it can be updated from another thread

Introduction

Recently, I had the known problem of setting the Text value of a ToolStripStatusLabel control from a thread other than the one that was handling it. This basically can happen when you fire an event from an independent thread method and want to display a message in the client application. The usual way to deal with this is to use the Invoke method of the control to delegate the operation so that it is thread-safe. Unfortunately, ToolStripStatusLabel doesn't have such a method. I searched awhile on the internet to see if someone had a solution to this problem, but I couldn't find any satisfying one.

So, I searched by myself for a solution thinking that Microsoft had surely thought about this. The solution is in the StatusStrip control that contains all of the ToolStrip controls. This class has the InvokeRequired and Invoke methods that are necessary to delegate the call on the right thread. I came out with two solutions, both of which work.

Extending the StatusStrip control

The first solution consists of adding a method to the StatusStrip control to safely set the Text property of the ToolStripStatusLabel it contains. The code to achieve this is given below.

public void SafeSetText(ToolStripLabel toolStripLabel, string text)
{
    if (InvokeRequired)
    {
        SetText setTextDel = 
            delegate(ToolStripLabel toolStrip, string textVal)
        {
            foreach (ToolStripItem item in base.Items)
            {
                if (item == toolStrip)
                {
                    item.Text = textVal;
                }
            }
        };

        try
        {
            Invoke(setTextDel, new object[] 
            { 
                toolStripLabel, text 
            });
        }
        catch
        {
        }
    }
    else
    {
        foreach (ToolStripItem item in base.Items)
        {
            if (item == toolStripLabel)
            {
                item.Text = text;
            }
        }
    }
}

The idea is quite simple. As there is no Invoke method in ToolStripStatusLabel, I use the one of StatusStrip and find on which item I must apply the Text change. The drawback of this technique is that I cannot directly call the Text property of ToolStripStatusLabel and so this property remains unsafe. However, this solution works.

Extending the ToolStripStatusLabel control

The second solution satisfies me better. I override the Text property of ToolStripStatusLabel and make it totally safe so that it is no longer possible to call the original Text property. I think this solution is more elegant and it can be used with other ToolStrip items of a StatusStrip. The code of this solution is given below.

public override string Text
{
    get
    {
        // Make sure that the container is already built
        if ((base.Parent != null) &&        
            (base.Parent.InvokeRequired))   // Is Invoke required?
        {
            GetString getTextDel = delegate()
            {
                return base.Text;
            };
            string text = String.Empty;
            try
            {
                // Invoke the SetText operation from the 
                // Parent of the ToolStripStatusLabel
                text = (string)base.Parent.Invoke(getTextDel, null);
            }
            catch
            {
            }
            return text;
        }
        else
        {
            return base.Text;
        }
    }    
    set
    {
        // Get from the container if Invoke is required
        // Make sure that the container is already built
        if ((base.Parent != null) &&       
            (base.Parent.InvokeRequired))   // Is Invoke required?     
        {
            SetText setTextDel = delegate(string text)
            {        
                base.Text = text;
            };

            try
            {
                // Invoke the SetText operation from the
                // Parent of the ToolStripStatusLabel
                base.Parent.Invoke(setTextDel, new object[] { value });
            }

            catch
            {
            }
        }
        else
        base.Text = value;
    }
}

As you can see in the code, this solution is more straightforward and doesn't need a separate method to set the Text property. The trick is to get the Parent of the ToolStrip item and call the Invoke method with the delegate to set the Text property. The only drawback I found to this method is that you cannot use SafeToolStripStatusLabel from the designer and must modify the code generated by the designer. However, there may be a way to tell the designer to use our SafeToolStripStatusLabel when we add it to the StatusStrip control.

Demo application

In order to demonstrate both methods, I built a simple demo application that can fire one event displayed with the SafeStatusStrip control and one event displayed with the SafeToolStripLabel control. This application uses a thread that waits to send either one event or the other when a button is pressed. The event handlers display a message in the status bar using one of the two methods described previously.

Screenshot - Safetoolstrip1.jpg

Screenshot - Safetoolstrip2.jpg

Points of interest

This code can be used for any ToolStrip control that you might use in a StatusStrip container. You can use it freely in your application by building a component DLL that will contain all your safe controls.

History

  • 6 July, 2007 -- Original version posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

orouit
Architect Consistel - Singapore
Singapore Singapore
Software Architect, COM, .NET and Smartcard based security specialist.
 
I've been working in the software industry since I graduated in Electrical and Electronics Engineering. I chose software because I preferred digital to analog.
 
I started to program with 6802 machine code and evolved to the current .NET technologies... that was a long way.
 
For more than 20 years I have always worked in technical positions as I simply like to get my hands dirty and crack my brain when things don't go right!
 
After 12 years in the smart card industry I can claim a strong knowledge in security solutions based on those really small computers! I'm currently back in the business to design the licensing system for the enterprise solution I'm currenly working on, using a .NET smart card (yes they can run .NET CLR!)
 
View my profile on LinkedIn
 
You can contact me for professional consulting by using the forum.

Comments and Discussions

 
QuestionConverting to VB PinmemberKestrel_rob5-Feb-09 4:08 
AnswerRe: Converting to VB Pinmemberorouit12-Feb-09 21:44 
GeneralRe: Converting to VB [modified] PinmemberKestrel_rob12-Feb-09 22:18 
AnswerRe: Converting to VB PinmemberGeorg Kohler7-Mar-09 17:02 
Generalfound a new way PinmemberPrateek Bahl17-Nov-08 10:04 
Generalthanks for your idea,I had done this Pinmemberwangkuang522-Apr-08 18:55 
Generalthanks for your idea,I had done this Pinmemberwangkuang522-Apr-08 18:55 
GeneralMore ideas Pinmemberjsakhtar16-Jul-07 20:37 
GeneralSuggestions PinmemberRichard Deeming10-Jul-07 9:35 
GeneralRe: Suggestions ->Thks Pinmemberorouit11-Jul-07 4:44 
GeneralPossible hole... PinmemberDrewS7-Jul-07 16:58 
GeneralRe: Possible hole... Pinmemberorouit9-Jul-07 1:54 
General"Unfortunately, ToolStripStatusLabel doesn't have such a method. I searched awhile on the internet to see if someone had a solution to this problem, but I couldn't find any satisfying one." PinmemberThe_Mega_ZZTer6-Jul-07 18:45 
AnswerRe: "Unfortunately, ToolStripStatusLabel doesn't have such a method. I searched awhile on the internet to see if someone had a solution to this problem, but I couldn't find any satisfying one." Pinmemberorouit9-Jul-07 1:57 
GeneralGot my 5 PinmemberMarc Leger6-Jul-07 17:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 6 Jul 2007
Article Copyright 2007 by orouit
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid