Click here to Skip to main content
Licence 
First Posted 6 Jul 2007
Views 31,669
Downloads 332
Bookmarked 28 times

A thread-safe ToolStripStatusLabel control

By | 6 Jul 2007 | Article
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

About the Author

orouit

Architect
Consistel - Singapore
Singapore Singapore

Member

Software Architect, COM, .NET and Smartcard based security specialist.
 
I've been working in the software industry since I finished my study of Electrical Engineering. I chose software because I prefered digital to analog.
 
I started to program with 6802 machine code and evolved to the current .NET technologies... that's a long way.
 
In almost 20 years I have always worked in technical position, management would be a regression for me 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 specialisation 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 CLR!)
 
You can contact me for professional consulting by using the forum.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionConverting to VB PinmemberKestrel_rob4:08 5 Feb '09  
AnswerRe: Converting to VB Pinmemberorouit21:44 12 Feb '09  
GeneralRe: Converting to VB [modified] PinmemberKestrel_rob22:18 12 Feb '09  
AnswerRe: Converting to VB PinmemberGeorg Kohler17:02 7 Mar '09  
Generalfound a new way PinmemberPrateek Bahl10:04 17 Nov '08  
Generalthanks for your idea,I had done this Pinmemberwangkuang518:55 22 Apr '08  
Generalthanks for your idea,I had done this Pinmemberwangkuang518:55 22 Apr '08  
GeneralMore ideas Pinmemberjsakhtar20:37 16 Jul '07  
GeneralSuggestions PinmemberRichard Deeming9:35 10 Jul '07  
GeneralRe: Suggestions ->Thks Pinmemberorouit4:44 11 Jul '07  
GeneralPossible hole... PinmemberDrewS16:58 7 Jul '07  
GeneralRe: Possible hole... Pinmemberorouit1:54 9 Jul '07  
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_ZZTer18:45 6 Jul '07  
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." Pinmemberorouit1:57 9 Jul '07  
GeneralGot my 5 PinmemberMarc Leger17:40 6 Jul '07  

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.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 6 Jul 2007
Article Copyright 2007 by orouit
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid