Adding a toggle button

Our final toolbar button will illustrate the ToggleButton style to show and hide the pixel data dialog created in chapter 8. Toggle buttons, as you may recall from chapter 9, provide two different states: one when the button is pressed in, and one when it is not.

We will do something a little different here that seems appropriate for our example. If you are keeping track of the images available in our image list, you may realize there are two images left, while only one more button. We will use one image when the button is pushed in, and the other when it is not. Figure 13.3 shows our application with the button pressed in and the PixelDlg form displayed.

Figure 13.3

The toggle button on our toolbar displays a green light when the pixel dialog is shown, and a red light otherwise.

Figure 13.3

The toggle button on our toolbar displays a green light when the pixel dialog is shown, and a red light otherwise.

This will require some coordination with the rest of the application to make sure the button is never pressed when the pixel dialog is hidden. We'll begin by creating the button and implementing the ButtonClick event support.

Add the toggle toolbar buttons

Action

Result

In the ToolBarButton Collection Editor, add two new toolbar buttons.

settings

Button

property

Value

8

Style

Separator

(Name)

tbbPixelData

9 (Pixel)

ImageIndex

6

Style

ToggleButton

ToolTipText

Show pixel data

Implement an AssignPixelData method in the MainForm.cs code window to adjust the button settings based a specified value.

How-to

Display the green light icon when the button is pushed, and the red light otherwise.

Note: This will be used by various methods to update the toggle button as the state of the pixel data dialog changes.

protected void

AssignPixelToggle(bool push)

tbbPixelData.Pushed = push;

tbbPixelData.ImageIndex = 7; tbbPixelData.ToolTipText = "Hide pixel data";

else

tbbPixelData.ImageIndex = 6; tbbPixelData.ToolTipText = "Show pixel data";

Update the ButtonClick event handler to adjust the state of both the dialog and the button when the toggle is clicked.

How-to a. When the button is pushed, invoke the Pixel Data menu to ensure the dialog is displayed.

b. Otherwise, hide the dialog if it is currently displayed.

c. Also call the AssignPixelToggle method to update the button settings.

private void toolBarMain_ButtonClick (object sender,

ToolBarButtonClickEventArgs e)

// Handle menu buttons

// Handle Pixel Data button if (e.Button == tbbPixelData) {

// Display pixel dialog menuPixelData.PerformClick();

else if (this._dlgPixel != null && _dlgPixel.Visible)

// Hide pixel dialog _dlgPixel.Hide();

// Update the button settings AssignPixelToggle(e.Button.Pushed), i

These changes implement the correct functionality for the button. When the button is pushed, a Click event for the menuPixelData menu is performed, which displays the dialog. When the button is unpushed,1 the dialog is hidden using the Hide method. In this later case we ensure that the dialog exists and is shown before trying to hide it. The AssignPixelToggle method adjusts the image and the tool tip to reflect the new state of the button.

You can run the program to see the button in action. If you do, you may notice that there are two problems we still need to address:

• The button is not pushed when the pixel data dialog is displayed using the View menu item.

• The button is not unpushed when the dialog is closed manually.

For the first problem, we simply need to adjust the button in the Click event handler for this menu. Let's do this before we discuss the second problem.

Update the toggle button when the Pixel Data menu is selected

Action

Result

4

Locate the menuPixelData_Click event handler in the MainForm.cs code window.

private void menuPixelData_Click

(object sender, System.EventArgs e)

{

5

Update this method to adjust the toggle button settings.

|| dlgPixel.IsDisposed)

dlgPixel = new PixelDlg(); dlgPixel.Owner = this;

nPixelDlglndex = album.CurrentPosition; Point p = pnlPhoto.PointToClient(

Form.MousePosition); UpdatePixelData(p.X, p.Y); AssignPixelToggle(true);

dlgPixel.Show();

}

Our second problem, that of the user closing the pixel data dialog by hand, is more problematic. Since this dialog is a nonmodal window, this dialog can be closed at any time. So we need a mechanism for notifying our main window whenever the dialog is closed.

If you recall, and as shown in step 5 in the previous table, the MainForm form is defined as the owner of the PixelDlg form. This ensures that both windows are

1 I know, I know. There is no such word as "unpushed." You know what I mean. I thought about the word "released," but unpushed seems much more packed with meaning.

shown when either window is displayed or minimized. We can take advantage of this relationship to ensure that our main window is notified when the pixel dialog is closed.

The trick is to force the MainForm window to activate whenever the PixelDlg dialog is closed. Our main form will then receive an Activated event, at which time we can update our button. Since the MainForm class derives directly from Form, we can handle this event by overriding the protected OnActivated method.

The following steps implement this mechanism.

Update the toggle button when the PixelDlg form is closed

Action

Result

6

In the PixelDlg.cs code window, override the onClosing method to activate the owner of the dialog, if any.

Note: Since the dialog may not be fully closed here if the MainForm. OnActivated method runs immediately, we set the Visible property to false to ensure the correct behavior occurs.

Also note that overriding the OnClosed method instead does not work because the owner property is no longer valid once the dialog has been closed.

protected override void OnClosing (CancelEventArgs e)

Visible = false; if (this.Owner != null) Owner.Activate()

base.OnClosing(e);

}

7

Back in the MainForm.cs code window, override the OnActivated method.

protected override void

OnActivated(EventArgs e)

{

8

If the pixel dialog does not exist, then make sure our button is not pushed down.

// Update toggle button if required if (_dlgPixel == null

|| dlgPixel.IsDisposed)

AssignPixelToggle(false);

}

9

Otherwise, set the button state based on the Visible property of the pixel dialog.

else

AssignPixelToggle( dlgPixel.Visible); base.OnActivated(e);

}

This code ensures that whenever the user closes the PixelDlg form, the main form is activated and the toggle toolbar button immediately updated. Compile and run the application to ensure that it works as expected.

TRY IT! Add two new menus to the top of the View menu called menuToolBar and menuStatusBar. Implement these menus to show and hide the corresponding controls in the application. Use the Visible property inherited from the Control class to identify the control's current state and set it to the opposite one. If you are careful, you can implement a single Click handler for both menus by using the sender parameter and observing that both objects are Control instances. When you run the program with these changes, note how the control shows or hides their contained buttons or panels as well.

This completes our discussion of toolbars. We now move on to the mostly unrelated but similarly named ToolTip class.

0 0

Post a comment

  • Receive news updates via email from this site