ProgressBar

A ProgressBar control visually indicates the progress of a time-consuming operation, especially one that does not provide any other indication that the machine is still processing. It might be used for file copy operations, attempts to make a network or internet connection, or a lengthy computation.

The ProgressBar class has just four commonly used properties that are not inherited from Control or some other base class, listed in Table 13-20.

Table 13-20. ProgressBar properties

Property

Value type

Description

Maximum

Integer

Read/write. The maximum value of the range displayed by the control. Default value is 100.

Minimum

Integer

Read/write. The minimum value of the range displayed by the control. Default value is 0.

Step

Integer

Read/write. The amount by which the progress bar is incremented when the PerformStep method is called. Default value is 10.

Value

Integer

Read/write. The current position of the progress bar. Default value is zero.

In addition to the properties listed in Table 13-20, two methods are commonly invoked. The Increment method takes an integer as an argument, incrementing the progress by that amount. The PerformStep method takes no arguments, but increments the progress bar by the amount specified by the Step property.

The programs listed in Example 13-15 (in C#) and Example 13-16 (in VB.NET) demonstrate a progress bar. In these examples, a button click triggers a counter to count up to 10,000. For every 100 counts, a label displays the current value of the counter and the progress bar is updated. The running program looks much like Figure 13-16.

Figure 13-17. ProgressBar control

Example 13-15. ProgressBar in C# (ProgressBar.cs)

using System; using System.Drawing; using System.Windows.Forms; namespace ProgrammingWinApps { public class ProgressBars : Form { ProgressBar pb; Label lbl; public ProgressBars( ) { Text = "ProgressBars"; Size = new Size(300,200); Button btn = new Button( ); btn.Parent = this; btn.Text = "&Start"; btn.Location = new Point((Size.Width / 2) - (btn.Width / 2), (Size.Height / 4) - btn.Height); btn.Click += new EventHandler(btn_OnClick); lbl = new Label( ); lbl.Parent = this; lbl.Size = new Size(100,23); lbl.Location = new Point((Size.Width / 2) - (lbl.Width / 2), btn.Bottom + 25); lbl.BorderStyle = BorderStyle.FixedSingle; lbl.TextAlign = ContentAlignment.MiddleCenter; lbl.Text = ""; pb = new ProgressBar( ); pb.Parent = this; pb.Location = new Point((Size.Width / 8), lbl.Bottom + 25); pb.Size = new Size((int)(Size.Width * 3 / 4), 20); pb.Minimum = 0; // the default value pb.Maximum = 100; // the default value } // close for constructor private void btn_OnClick(object sender, EventArgs e) { int limit = 10000; int cntr = 0; pb.Value = 0; pb.Step = 1; for (int i = 0; i < limit; i++) { cntr ++; if (cntr % 100 = = 0) { lbl.Text = cntr.ToString( ); pb.PerformStep( ); Application.DoEvents( ); System.Threading.Thread.Sleep(20); } } } static void Main( ) { Application.Run(new ProgressBars( )); } } // close for form class } // close form namespace

Example 13-16. ProgressBar in VB.NET (ProgressBar.vb)

Option Strict On imports System imports System.Drawing imports System.Windows.Forms namespace ProgrammingWinApps public class ProgressBars : inherits Form dim pb as ProgressBar dim lbl as Label public sub New( ) Text = "ProgressBars" Size = new Size(300,200) dim btn as new Button( ) btn.Parent = me btn.Text = "&Start" btn.Location = new Point( _ CType((Size.Width / 2) - (btn.Width / 2), integer), _ CType((Size.Height / 4) - btn.Height, integer)) AddHandler btn.Click, AddressOf btn_OnClick lbl = new Label( ) lbl.Parent = me lbl.Size = new Size(100,23) lbl.Location = new Point( _ CType((Size.Width / 2) - (lbl.Width / 2), integer), _ btn.Bottom + 25) lbl.BorderStyle = BorderStyle.FixedSingle lbl.TextAlign = ContentAlignment.MiddleCenter lbl.Text = "" pb = new ProgressBar( ) pb.Parent = me pb.Location = new Point( _ CType((Size.Width / 8), integer), lbl.Bottom + 25) pb.Size = new Size(CType((Size.Width * 3 / 4), integer), 20) pb.Minimum = 0 ' the default value pb.Maximum = 100 ' the default value end sub ' close for constructor private sub btn_OnClick(ByVal sender as object, _ ByVal e as EventArgs) dim limit as integer = 10000 dim cntr as integer = 0 dim i as integer pb.Value = 0 pb.Step = 1 for i = 0 to limit cntr = cntr + 1 if cntr mod 100 = 0 then lbl.Text = cntr.ToString( ) pb.PerformStep( ) Application.DoEvents( ) System.Threading.Thread.Sleep(40) end if next end sub public shared sub Main( ) Application.Run(new ProgressBars( )) end sub end class end namespace

In these programs, two controls are declared as member variables: the progress bar and the label that will display the current value.

In the constructor, all three controls are instantiated and specified. The size and location of all controls, including the progress bar, are set based on the size of the form and the position of the control located above it on the form, as appropriate.

The progress bar has its Minimum and Maximum properties set to the default values of 0 and 100, respectively. In this example, these values lend themselves to easy calculation. However, other applications may call for different values. For example, if the progress bar indicates the time it takes to stream a number of lines to a file, it would make more sense to set the Maximum property to the total number of lines to be streamed.

In the button Click event handler, three integers are declared and instantiated for incrementing a counter. Also, the progress bar's Value property is reinitialized to 0 (necessary if the button is clicked a second or subsequent time) and the Step property is set to 1. This latter property is the amount by which the control is incremented when the PerformStep method is called.

Inside the for loop, which increments the counter, the modulo operator updates both the label and the progress bar every 100 counts.

if (cntr % 100 = = 0)

if cntr mod 100 = 0 then

Within the loop, the label control's Text property is updated and the progress bar's PerformStep method is called. Then the static Application.DoEvents method is called to allow the form to repaint itself without having to wait until the Click event finishes its processing. If the DoEvents method is not called, you will not see the updated label, although the progress bar would still update properly.

The values used for the Step property and the modulo function are related. The modulo function updates the display every 100 counts, which is 1 percent of the limit. The Step property is also 1 percent of the Maximum value, so they correspond.

As an alternative to using the PerformStep method, you could omit the line that sets the Step property and replace the call to PerformStep with the appropriate following line:

pb.Value = (int)((float)cntr/(float)limit * 100) ;

pb.Value = _ CType((CType(cntr, single) / CType(limit, single) * 100), integer)

As another alternative to using the PerformStep method, you could again omit the line that sets the Step property and replace the call to PerformStep with the following line (the same in both languages):

pb.Increment(1)

A 40 millisecond pause is introduced every 100 counts with a call to the static Thread.Sleep method. This slows things down so they can be observed.

Категории