Status Bars

Status bars can provide additional information about your program, as well as to add controls to the bottom of your form for informational display. A status bar consists of a number of Panels (each of which may contain other controls), and you can display information directly on the status bar itself.

In the next example, you will modify the previous example to add a status bar that will display both the current time and the amount of time the application has been running, as shown in Figure 18-23.

Figure 18-24. Status bar demonstration

In addition, when you click on or hover over menu choices, the time panels will disappear and information about the menu choice will be displayed, as shown in Figure 18-24.

Figure 18-25. Hiding the panels

To add some spice to this application, when you left-click on the status bar, the elapsed timer will be reset to zero, and when you right-click on the status bar, a context menu will pop up, offering to reset, suspend, or resume the timer as shown in Figure 18-25.

Figure 18-26. Pop-up menu

The complete source code is greatly duplicative of the previous example, so it will not be shown here, but it can be downloaded as StatusBarsCS or StatusBarsVB. The relevant changes are detailed in the coming pages.

To get started, copy the ToolBarsCS or ToolBarsVB solution and change all the relevant filenames and text from ToolBars to StatusBars, as described in Chapter 1. Open your new StatusBarsVB or StatusBarsCS program and double-click on Form1 to display the form.

18.5.1 Analysis

First, add a StatusBar object to your form. Notice that when you drag this object onto your form, it adheres to the form (unlike the Menu, which must be set as a property of the form). This is just Visual Studio .NET's way of keeping life interesting.

The StatusBar object itself has a great many properties, methods, and events, most inherited from Control. Some of the most important properties are shown in Table 18-9.

Table 18-9. Status bar properties

Property

Type

Description

Dock

DockStyle

Read/Write. DockStyle is an Enumeration (Bottom, Fill, Left, None, Right, Top) that determines how the status bar is docked to the form.

Panels

StatusPanelCollection

Read-only. The collection of Panels in the status bar.

ShowPanels

Boolean

Read/Write. If true, the panels are displayed: otherwise, the Text property is displayed. The default is false.

SizingGrip

Boolean

Read/Write. If true (the default), a sizing grip is displayed in the lower-right corner of the status bar.

Text

String

Text that is displayed if the ShowPanels property is set to false.

Your first task is to add a couple of panels to the status bar. In this case, you'll want three. One will hold the place for the menu information, and the other two will be for the time and elapsed time, respectively.

Status bar panels are encapsulated in the StatusBarPanel class, which also has several useful properties. These properties will be discussed next when you create the Panels.

Navigate to the Panels (Collection) property and click on the button to open the StatusBarPanel Collection Editor. Click Add to add your first panel, which you will name pnlMenuHelp. Set the AutoSize property of this panel to Spring. This property is an enumeration of type StatusBarPanelAutoSize, whose three possible values are shown in Table 18-10.

Table 18-10. StatusBarAutoSize enumeration

Value

Description

Contents

The width is determined by the contents.

None

The panel does not change size when the status bar control resizes.

Spring

The panel shares available space within the status bar with other properties set to Spring.

The complete set of properties to set is shown in Figure 18-26.

Figure 18-27. Properties for pnlMenuHelp

The second panel you need to add is for the current time. Its properties are shown in Figure 18-27.

Figure 18-28. pnlCurrentTime properties

Notice that this panel has its Alignment set to Center (so that the time is centered) and its Border style set to Sunken. In addition, the AutoSize property is set to Contents so that the panel will be sized to the display string.

Finally, add a third panel for the Elapsed time, as shown in Figure 18-28, noting the minor differences from the CurrentTime panel. Notice that the ToolTipText for this panel is "Time you've had this application open".

Figure 18-29. Elapsed time panel

If you run the application now, you'll find that the status bar displays only "StatusBar1" and no panels are visible. Back in design mode, click on the status bar and set the ShowPanels property to true. Run the application and the panels display, but the time is not shown and clicking on the panel does nothing.

18.5.1.1 Setting the timer

To get the panels to display the current and elapsed time, you'll need a timer, as described in Chapter 1. Add a timer to the form, and then set the timer in the +constructor:

timer1.Interval = 1000; timer1.Start( );

This creates a timer that will fire an event every second (the Interval property is in milliseconds).

You'll also need a private member variable to keep track of the starting time (to display elapsed time):

private DateTime startTime;

Private startTime As DateTime

In your constructor, you'll initialize the startTime member variable with the current time:

startTime = DateTime.Now;

The Timer will fire the Tick event. Double-click on the timer in your designer to set up the event handler. In the event handler, you'll want to do two things. First, set the panel for the current time to the current time:

private void timer1_Tick(object sender, System.EventArgs e) { pnlCurrentTime.Text = DateTime.Now.ToLongTimeString( );

Second, compute the elapsed time, and then display it in the panel for the elapsed time:

TimeSpan elapsedSpan = DateTime.Now - this.startTime; DateTime elapsed = DateTime.Parse(elapsedSpan.ToString( )); pnlElapsedTime.Text = "Elapsed: " + elapsed.ToString("HH:mm:ss"); }

Private Sub Timer1_Tick( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Timer1.Tick pnlCurrentTime.Text = DateTime.Now.ToLongTimeString( ) Dim elapsedSpan As TimeSpan = (DateTime.Now).Subtract(Me.startTime) Dim elapsed As DateTime = DateTime.Parse(elapsedSpan.ToString( )) pnlElapsedTime.Text = "Elapsed: " + elapsed.ToString("HH:mm:ss") End Sub

If you run the application now, your panels will be updated.

18.5.1.2 Updating the status bar based on menu information

You'll want to hide the panels when the user clicks on a menu choice. That is easy to do if you know when the user has begun clicking on menu items and when the user has finished. The form itself has two events to which you can respond: MenuStart and MenuComplete. You need write only the event handlers:

private void OnMenuStart(object sender, System.EventArgs e) { statusBar1.ShowPanels = false; } private void OnMenuComplete(object sender, System.EventArgs e) { statusBar1.ShowPanels = true; }

Private Sub Form1_MenuStart( _ ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles MyBase.MenuStart StatusBar1.ShowPanels = False End Sub Private Sub Form1_MenuComplete( _ ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles MyBase.MenuComplete StatusBar1.ShowPanels = True End Sub

VB.NET programmers note: the events MenuStart and MenuComplete are listed under BaseClassEvents.

When the user actually does highlight on a menu choice, update the information in the status bar for that MenuItem. Each MenuItem has a Select event, and there is no reason not to use a common event handler for this event. In a sophisticated program, you will want to determine which menu choice the user is considering and provide meaningful help, but for now you can stub out the event handler:

private void OnMenuSelect(object sender, System.EventArgs e) { MenuItem mi = (MenuItem) sender; statusBar1.Text = "Information here about " + mi.Text; }

Private Sub OnMenuSelect( _ ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles mnuFile.Select, mnuFileOpen.Select, mnuFileClose.Select, _ mnuFileSave.Select, mnuFileSaveAs.Select, mnuEdit.Select, _ mnuEditCopy.Select, mnuEditPaste.Select, mnuOption1.Select, _ mnuOption2.Select, mnuOption3.Select, mnuOptions.Select, _ mnuRadioOptions.Select, mnuRadioOption1.Select, _ mnuRadioOption2.Select, mnuRadioOption3.Select, mnuSpecial.Select, _ mnuODVote.Select, mnuODShazam.Select, mnuMerge.Select, _ mnuMenu1.Select, mnuMenu11.Select, mnuMenu12.Select, _ mnuMenu13.Select, mnuMenu14.Select, mnuMenu2.Select, _ mnuMenu21.Select, mnuMenu22.Select, _ mnuMenu23.Select, mnuMenu24.Select, mnuWindow.Select Dim mi As MenuItem = CType(sender, MenuItem) StatusBar1.Text = "Information here about " + mi.Text End Sub

18.5.1.3 Handling status bar events

The status bar itself has several events to which you might want to respond. The default event is PanelClick. In this example, you'll implement an event handler to test which button the user has pressed if it is the right button, you'll zero the elapsed timer. This is facilitated by the StatusBarPanelClickEventArgs parameter passed into the event handler, which can, among other things, provide access to the mouse button that was clicked:

private void statusBar1_PanelClick( object sender, System.Windows.Forms.StatusBarPanelClickEventArgs e) { if ( e.Button. = = MouseButtons.Left) { startTime = DateTime.Now; } }

Private Sub StatusBar1_PanelClick( _ ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.StatusBarPanelClickEventArgs) _ Handles StatusBar1.PanelClick If e.Button = MouseButton.Left Then startTime = DateTime.Now End If End Sub

18.5.1.4 Adding a context menu

Finally, to handle the right mouse button, you'll add a context menu. Do so as described earlier in Section 18.2.9, by adding three entries: Reset Time, Suspend Time, and Resume Time. Name the context menu pnlContextMenu, and assign it to the ContextMenu property of the status bar, either in the properties window as shown in Figure 18-29 or, if you prefer, programmatically in the constructor.

public Form1( ) { InitializeComponent( ); timer1.Interval = 1000; timer1.Start( ); startTime = DateTime.Now; statusBar1.ContextMenu = pnlContextMenu;

Add three menu items to the context menu: Reset Time, Suspend Time, and Resume Time.

Figure 18-30. Adding the context menu

The Resume Time option should not be visible (or it should be disabled) when the timer is running, and the Suspend Time option should not be visible, or it should be disabled when the timer is suspended. In addition, when the time is resumed, the elapsed time (between suspension and resumption) should be subtracted out. All of this is left as an exercise for the reader to keep the example simple and prevent this book from weighing more than it already does.

In either case, you now must implement the three event handlers:

private void MnuResetTime_Click(object sender, System.EventArgs e) { startTime = DateTime.Now; } private void mnuSuspendTime_Click(object sender, System.EventArgs e) { timer1.Stop( ); } private void mnuResumeTime_Click(object sender, System.EventArgs e) { timer1.Start( ); }

Private Sub mnuResetTime_Click( _

ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles mnuResetTime.Click startTime = DateTime.Now End Sub Private Sub mnuSuspendTime_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles mnuSuspendTime.Click Timer1.Stop( ) End Sub Private Sub mnuResumeTime_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles mnuResumeTime.Click Timer1.Start( ) End Sub

Категории