StatusBars in Real Applications


In this article we will investigate the Status Bars found in the .NET Framework, to read this article and get the most of it you must have a good working knowledge with C#, OOP and WF.NET.

Introduction to Status bars:

Most of you (who program on the win32 platform using former Microsoft programming languages like Microsoft Visual C++) are familiar with status bars. Most of the modern Windows applications display some useful information for the users in many different ways (tool tips, Help Menu, Status Bar) and Status Bar is a primary way to display keys and application status and maybe provide information related to cursor position or maybe information related to the current performed task.

Status Bars display information as textual information or as images that will explain the current task. Famous example of that is Microsoft Word's status bar which display many information for you like page number, the total number of pages, the current line number, columns, and some keys status like the status of the insert key, and some other information is graphical representation (images) and an example of that while you are typing you will find an open book and a pencil as you write and when you stop writing it will change to an open book and a red check mark over it also when you print you will find a printer icon printing pages while you are printing all this useful information help you track many processes in your applications and it will improve user interaction for better and faster application use.

In other words (technically), the status bar control display information related to objects and other controls on the form, for example if you have a menu on your form you can write code that will display a textual description about each menu item in the menu. In this article we will learn about the members of the status bar control and how we can use them to create powerful status bar in our applications.

The Status bar Class:

The Status Bar class is used to create a Status bar control on a form. This control is used to display textual information or graphical information related to the application status or the performed task. The Status Bar class is part of the System.Windows.Forms namespace and it's inherits from the Control class.

Each form can have its own status bar but it's not make sense so in real 'applications there is only one Status Bar control for a given application (but in some situation maybe you have to have more than one Status Bar for your application). When you have only one Status Bar for your application its contents can be changed depending on the active form or the current task and actually I think It's the power of the Status Bar control.

The Status Bar control can display 2 types of information: a normal text as a description for other controls on the form like Menus and Toolbars buttons and we call it flyby text because it will change each time the mouse moves over a control also we can display text in the Status Bar control while our application is performing some operation (like opening a file or access the internet). Another type of information that we can display is application and keys state, and I will talk about it later when we learn about panels.

Status bar Class members

Because the Status Bar control inherits from the control class I will not discuss all the inherited members and I will go directly to the Status bars Members and some of the control class members.

Status Bar properties Properties Description
ContextMenu Use this property to get or set the context menu associated with the control.
Controls Gets a collection of the controls contained by this control.
Created Gets a value indicating whether the status bar has been created
Dock Gets or sets the dock setting for the status bar and by default the value is DockStyle.Bottom so you will find the control docked to the bottom of the form when you create it.
HasChildren Gets a value indicating whether the control contains one or more child controls.
Panels Gets the statusBarPanelCollection class containing the set of statusBarPanel objects managed by this status bar.
Parent Gets or sets the parent container of the control.
ShowPanels This property related to whether you want to show the panels or a simple text in the Status Bar control. If you set it to true then it will show the panels and hide the text and if false then it will show the text and hide the panels.
SizingGrip Gets or Sets a value indicating whether a sizing grip should be displayed in the lower-right corner of the Status Bar. You can use this grip to resize the form. The Default setting is true.
TabStop Gets or Sets Whether the control is a tab stop on the form. The default value for status bar is false so you will not be able to tab to the status bar.
Text Gets or Sets the text for the status bar. This is displayed on the status bar only if the ShowPanels is set to false.
Status Bar Methods Methods Description
BringToFront Bring the control to the front of the z-order.
Contains Retrieves a value indicating whether the specified control is a child of the control. For example you may need to know if the status bar control contains a panel object called PrinterPanel so you can use this method to know that.
FindForm Retrieve the form that the status bar created on. 
GetType Get the type of the current instance
Hide Hide the control from the user. You may need to hide the status bar in some situations.
Invalidate Overloaded. Invalidates a specific region of the control and causes a paint message to be sent to the control.
ResetText Resets the Text property to its default value. The default value of the text property is "Statusbar1".
SendToBack Sends the control to the back of the z-order.
Show Displays the control to the user.
Status Bar events events Description
PanelClick Occurs when a panel on the status bar is clicked
DrawItem Occurs when an owner-drawn status bar panel must be redrawn
Resize Occurs when the control is resized.
TextChanged Occurs when the value of the text property changed 

I think these are the most common members you will deal with them, let's go and add a status bar control to a Windows Application.

Adding Status bar Control to a Windows Application

Create a new windows application and name it statusBarTest and double click on the button named "StatusBar" in the toolbox window then you will find that a status Bar control named "statusBar1" added to your form (Form1). Figure 1 displays Form1 and a Status Bar control created on it.

Figure 1.1

Note that the status bar instance is docked to the bottom of the form because the Dock property is set to DockStyle.Bottom by default. Also note that the text displayed on the status bar is the value of the text property and here the default value is "statusBar1".

Let's look at the changes made to the InitializeComponent() method in the Visual Studio.NET auto generated code after adding the StatusBar control.

#region
Windows Form Designer generated code
/// <summary>
///
Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.statusBar1 = new System.Windows.Forms.StatusBar();
this.SuspendLayout();
//
// statusBar1
//
this.statusBar1.Location = new System.Drawing.Point(0,251);
this.statusBar1.Name = "statusBar1";
this.statusBar1.Size = new System.Drawing.Size(292, 22);
this.statusBar1.TabIndex = 0;
this.statusBar1.Text = "statusBar1";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.AddRange(new System.Windows.Forms.Control[] {this.statusBar1});
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion

Before we discuss this code notice that the form contains only this StatusBar and there are no other controls over it.

The first line of code in the InitializeComponent() method create a new object (new instance) of the StatusBar type. The next 5 lines set the properties of the StatusBar control (location, name, size, tabindex and text). Normally you will not tab into a status bar control though VS.NET will set the tabindex property and that's to ensure that all controls on the form have a unique index (a mechanism to avoid bugs). There is a property called TabStop which if you set it to false you will not be able to tab into the control and that's exactly what statusbar control does, it will set the TabStop property to false so the control will not support tabbing.

Most important thing you must note about the above code is placing the statusbar on the form (the z-order). Look at the following line of code (from the above code):

this
.Controls.AddRange(new System.Windows.Forms.Control[]
{
this.statusBar1
}

This line adds the statusBar1 object to the Controls collection of the Form1. So what's new? Nothing new because we have only one control on the form. But to see the z-order placing mechanism let's add another control like a button.

Add the button control so the form will be like this:

Now let's look again at the previous line:

this
.Controls.AddRange(new System.Windows.Forms.Control[] {
this.button1,this.statusBar1});

Although we added the statusbar instance first the button control is added to the form first and that's because of the z-order (if you don't know about z-order wait for my next article about it).

Important Note:

You may notice that I used the words "statusbar object" in place of "statusbar control" and many of you (who don't know much about OOP) will get confused. In fact a control is a class with a visual representation. For example, the textbox control is just a textbox class with a visual representation (a rectangular where we can type characters). So when I say statusbar control I mean the statusbar class. Almost all of the windows form controls that shipped with the .NET Framework are classes with a visual representation (but there are many controls that don't have a visual representation).

Working with StatusBar control

As I said in the beginning of the article that statusbar control can display information as a simple text also the statusbar control can display information in panels. A panel (as we will see in later section) is an area of information on the statusbar. For now let's create a windows application that contains a statusbar control and a File menu. In this application we will display simple text information in the status bar when the user selects a menu item from the file Menu.

Create a windows application and name it "StatusBarText". Then add a statusbar control and a MainMenu object and you will get a form like this:

Create a submenu items for the File menu. Create the standard New, Open and Close menu items in the file menu. So the form will look like the following:

Before we write the code that will display some information when selecting a menu item we need to set the text of the statusbar control to empty string in the event handler of the form load event so when the form is loaded the statusbar contains empty string. To do this double click empty space on the form and VS. NET will create the event handler for you like following:

private
void Form1_Load(object sender, System.EventArgs e)
{
}

Now write the following line of code (inside the event handler) to set the text property of the statusbar control to an empty string.

this.statusBar1.Text = " ";

Run the application and you will not find the text "statusBar1" written in the statusbar control.

Now let's begin writing the code for displaying simple information when the user selects a menu item from the File menu. To perform this operation we need to handle the event select of the menu items in the File menu so when the user select a menu item we will display some helpful information is the statusbar control. Let's do just this:

As you might now VS. NET will help you create the event handler for the select event just select the first menu item in the file menu (New) and then right click to get a pop-up menu then select properties to get to the properties window of the New menu item. Select the events icon to view the available events for the menu item. You will get the next window:

From the events window now we know that there are only five events for the menu item. In our application we need to implement an event handler to the select event. Double click on the select in the events window and VS. NET will generate an event handler for the New menu item named menuItem2_Select and VS. NET will take you to the code window and specially to that handler which look like:

private void menuItem2_Select(object sender, System.EventArgs e)
{
}

Here we will write our code as following:

private void menuItem2_Select(object sender, System.EventArgs e)
{
this.statusBar1.Text = "Use New to Create a new application";
}

Pretty simple we just used the text property of the statusbar control to set the text to "Use New to Create a new application".

Let's do it with the other menu items. I will not mention the steps because I mentioned it in the new menu item. The next is the code for the event handlers for the select event of the (Open and Close menu items).

private void menuItem3_Select(object sender, System.EventArgs e)
{
this.statusBar1.Text = "Use Open to Open an application";
}
private void menuItem4_Select(object sender, System.EventArgs e)
{
this.statusBar1.Text = "Use Close to Close the application";
}

Run the application to test the statusbar text changing whenever you select another menu item. Something to note about this application is that the statusbar text will store the last selected menu item so if the New menu item was the last selected menu item then the text "Use New to Create a new application" and it's not appropriate that our statusbar control display this text when no menu item is selected so we will use the event MenuComplete provided by the Form class which occurs whenever menu lose focus so we can write code to set the statusbar text property to empty string when the menu lose the focus.

In this application I will not implement an event handler for the MenuComplete event but I will override the method OnMenuComplete which is Microsoft recommendation.

Important Note:

There are 2 ways to handle events:

1. You can override the On* methods (like our method OnMenuComplete) which is created inside many of the .NET Windows Forms classes like the Form class and this method will be called whenever the related event happen but you can only use it if you are inheriting a class, I mean I can use On* methods if I'm inheriting from a class support them so I can override them. Seems logical right?
2. You can create an event handler for the event which will be called whenever the event happen.

In fact Microsoft recommend that you override the On* methods in the derived classes instead of creating an event handlers for the events and that's for better performance and more organizing for our code. Also don't forget to call the base method to do its part of the job, I mean when you override a base class method don't forget to call the base class method in the derived method. For example if you going to override OnMenuComplete method in our form Form1 don't forget to call the Form class's method OnMenuComplete inside your method.

Open the code window and then write the following method:

protected override void OnMenuComplete(System.EventArgs e)
{
this.statusBar1.Text = " ";
base.OnMenuComplete(e);
}

Here I override the method OnMenuComplete which our form inherits it from the Form class. This method is called each time the menu loses focus. This code line inside the method will set the text property to an empty string.

Now let's move to more advanced programming techniques in statusbar control.

StatusBar Panels

Statusbar panels are merely separate areas in the statusbar that can display text or graphical information. Statusbar panels make our control look better and it provides you with a way to display more than one piece and kind of information. Some of you may call it panes. Each StatusBar Panel is an instance of the StatusBarPanel class and the StatusBar control has a property called panels which is a collection of StatusBarPanel objects. Next is the table of most important members of the StatusBarPanel class. 

StatusBarPanel
properties
Properties Description
MinWidth Gets or sets the minimum width for the panel
Parent This property will get the StatusBar object that contains this panel.
Alignment Gets or sets the HorizontalAlignment for the panel's text
AutoSize Gets or sets how the panel is sized within the status bar. And it takes its values from StatusBarPanelAutoSize enumeration which we will discuss in the last of the article.
BorderStyle Gets or sets the type of border to display for the panel. And it takes its values from StatusBarPanelBorderStyle enumeration which we will discuss in the last of the article.
Style Gets or sets the style used to draw the panel. And it takes its values from the StatusBarPanelStyle enumeration which we will discuss in the last of the article.
Text Gets or sets the text for the panel
ToolTipText Gets or sets the tool tip for the panel
Icon Gets or sets the icon to display within the status bar panel

Adding StatusBar Panels to our StatusBar control

Let's add 2 panels to our statusbar control using Visual Studio.NET. To add panels to our statusbar control I will use the Panels property in the property window. Go to the design window and right click on the statusbar control to get the pop-up window then choose properties. Now navigate to the Panels property and click on the entry named (Collection) which will bring to you a … button then click on that button and you will get the StatusbarPanelCollection Editor which we will use to add panels to our statusbar. This is the StatusbarPanelCollection Editor:
 

Let's add our first Panel; click on the Add button in the editor and your editor will look like the next figure:

By default Visual Studio.NET added a statusBarPanel named statusBarPanel1 and a default values for its properties which we going to change it. Let's change some properties.

Change the statusBarPanel1 object's properties to the following:

BorderStyle = Raised
Width = 200

And then click the ok button to get back to the design window. Note that our statusBarPanel still invisible because the property ShowPanels has a value of false so you need to change it to true from the properties window. Because the statusbar text property is useless now we need to change our code that uses statusBar1.Text property to statusBarPanel1.Text property and the best way to do this is via the Edit  Find and Replace  Replace menu item. Now open the code window and then select the Find and Replace from the Edit menu and select Replace from the submenu then type this.statusBar1.Text in the Find What: entry and type this.statusBarPanel1.Text in the Replace With: entry and click on Replace All button. Run the application and you will note that our statusbar will perform as before except it has one statusBarPanel to display information instead of its text property. Let's look at the changes made to the Visual Studio.NET auto generated code.

The only thing that you must know about is the next few lines:

((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).BeginInit();

((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).EndInit();

You may find that this line of code is a little strange because the statusbar is not just a control but it's a component. The statusBarPanel object must be fully initialized before it can be used within the statusbar control. The ISupportInitialize interface specifies that the statusBarPanel object will have 2 methods (the methods of the interface) which will begin and end the object initialization process before it can be used by the statusbar control and these methods are (BeginInit() and EndInit() methods)

After VS.NET will set the properties for the Panel it will add it to the statusBarPanel collection in the following line:

this
.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {this.statusBarPanel1});

Let's create our second statusBarPanel. From the StatusbarPanelCollection Editor create a second panel and leave the default properties values.
 

This Panel will tell us if the Insert button has been pressed or not. Let's write the code step-by-step, first we need 2 strings which will be displayed depending on the status of the Insert Button ("Insert Pressed", "Insert Not pressed"). When the application is first loaded we can display the string "Insert Not Pressed" in the second Panel and it makes sense because the application just loaded and the user didn't press the Insert key yet. So we can set the text property of this Panel to the string "Insert Not Pressed" in the event handler of the load event of the form, to do this double click on any empty space on the form to get to the event handler and write the following code:

this.statusBarPanel2.Text = "Insert Not Pressed";

So the event handler will look like:

private void Form1_Load(object sender, System.EventArgs e)
{
this.statusBarPanel1.Text = " ";
this.statusBarPanel2.Text = "Insert Not Pressed";
}

our next step is to write code that will test for pressing the Insert Key and the best place to write that code is in OnKeyDown method of the form class which called each time a key is down ( not yet pressed just you put your finger on the key and press it and before you release it. So in this method we can test if the user press the Insert key or not and based on that we will change the string in the second Panel, Ok? Let's do just that.
The first thing we need to declare a private variable of type bool in the Form1 class (or whatever name you called your form class) and we will use this variable as a flag to know if the user was activated or deactivated the Insert Key so write the following line of code in the first of the Form1 class:

private bool active = false;

I initialized its value to false because when the application first start the Insert Key is not pressed (is not active) so false is the right value. Then we need to override the OnKeyDown method of the Form1 class to test for the pressed key. Now write the following method in the Form1 class:

protected override void OnKeyDown(KeyEventArgs e)
{
if((e.KeyValue == 45) && (active == false))
{
this.statusBarPanel2.Text = "Insert Pressed";
active = true;
}
else if((e.KeyValue == 45) && (active == true))
{
this.statusBarPanel2.Text = "Insert Not Pressed";
active = false;
}
base.OnKeyDown(e);
}

This method is pretty easy, we use the KeyValue property of the e parameter which get the Keyboard value for the pressed key and because the Insert Key value is 45 then we use it, also we use the flag variable which test if the user pressed the Insert Key or not yet so if the user has not pressed the Insert Key yet then the if statement evaluate to true and the code inside execute which will set the text property of the second Panel to Insert Pressed and set the flag variable to true so the user now pressed the key. Next time your press the insert key the else if statement will evaluate to true and begin executed because the active variable now is true (the user pressed the Insert key last time) and the code inside will execute which will set the text of the second panel to 'Insert Not Pressed" and set the active variable to false (that means, the user deactivated the Insert Key). Now your form will look like this in the runtime:


 

I think by now you know how much important having a StatusBar in your application to minimize users problems and improve program interaction by providing helpful information like what we did here. When you add statusBarPanels using the editor you find 3 properties that takes a values from enumerations let's talk about that.

StatusBar and Enumerations

The statusBarPanel class has 3 properties that take values from enumerations these are (AutoSize property which takes its values from StatusBarPanelAutoSize enum, BorderStyle property which takes its values from StatusBarPanelBorderStyle property and the Style property which takes its values from the StatusBarPanelStyle enum).

StatusBarPanelAutoSize Enumeration Values Description
Contents The width of the panel expands or contracts to fit the actual contents of the panel
None The width of the panel is fixed based on the width property setting. This is the default.
Spring The width of the panel expands or contacts to share the available space with other panels that have the Spring size setting.
StatusBarPanelBorderStyle Enumeration Values Description
None The panel is displayed with no border.
Raised The panel is displayed with a raised border.
Sunken The panel is displayed with a sunken border. This is the default.
StatusBarPanelStyle Enumeration Values  Description
OwnerDraw The panel is drawn by the owner, using the DrawItem event in the StatusBar class.
Text The panel is drawn by the system using the Text property of the panel.

I think by now you know much about Status Bars but still another important subject we must touch, in our next part of that article, it's owner-drawn status bar's panels.