Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Manning - Windows Forms Programming With CSharp.pdf
Скачиваний:
72
Добавлен:
24.05.2014
Размер:
14.98 Mб
Скачать

Figure 16.8 The title bar for our MDI application must handle the various types of child forms the application can display.

We should also point out that MDI child forms do not receive the Activated or Deactivate events. As a result, when converting from a single document interface into a multiple document interface, any tasks performed in these events must now be handled via another mechanism. Often the MdiChildActivate event can handle the work previously done in these events. Another option is to use the focus-related events, such as the Enter or Leave event. We will look at the activation events in our MainForm window in a moment.

Let’s implement an MdiChildActivate event handler to update the title bar for our application.

UPDATE TITLE BAR IN THE PARENT FORM

 

Action

Result

 

 

 

1

In the ParentForm.cs code

protected override void OnMdiChildActivate

 

window, override the protected

(System.EventArgs e)

 

OnMdiChildActivate method.

{

 

 

 

 

 

2

Implement this method to set

SetTitleBar();

 

the title bar for the MDI

base.OnMdiChildActivate(e);

 

application.

}

 

 

 

 

 

3

In the MainForm.cs code

public string AlbumTitle

 

window, add an AlbumTitle

{

 

property to retrieve the title of

get { return _album.Title; }

 

}

 

the currently displayed album.

 

 

 

 

 

554

CHAPTER 16 MULTIPLE DOCUMENT INTERFACES

UPDATE TITLE BAR IN THE PARENT FORM (continued)

 

Action

Result

 

 

 

4

Back in the ParentForm.cs code

protected void SetTitleBar()

 

window, implement the

{

 

SetTitleBar method to

Version ver

 

= new Version(Application.ProductVersion);

 

retrieve the version number for

 

 

 

the application.

 

 

 

 

5

If the active child is a MainForm

string titleBar

 

object, include the album title in

= "{0} - MyPhotos MDI {1:#}.{2:#}";

 

the title bar.

if (ActiveMdiChild is MainForm)

 

 

 

How-to

{

 

Cast the active child to a

string albumTitle

 

= ((MainForm)ActiveMdiChild).AlbumTitle;

 

MainForm object in order to

 

this.Text = String.Format(titleBar,

 

retrieve the current album title.

albumTitle, ver.Major, ver.Minor);

 

 

}

 

 

 

6

If the active child is a PixelDlg

else if (ActiveMdiChild is PixelDlg)

 

object, display the string “Pixel

{

 

Data” in the title bar.

this.Text = String.Format(titleBar,

 

"Pixel Data", ver.Major, ver.Minor);

 

 

 

 

}

 

 

 

7

Otherwise, just display the

else

 

version number in the title bar.

{

 

 

this.Text = String.Format(

 

 

"MyPhotos MDI {0:#}.{1:#}",

 

 

ver.Major, ver.Minor);

 

 

}

 

 

}

 

 

 

8

Also set the title bar in the

protected override void OnLoad(EventArgs e)

 

OnLoad method.

{

 

Note: This sets the title bar as

PixelDlg.GlobalMdiParent = this;

 

SetTitleBar();

 

the application begins, before

base.OnLoad(e);

 

any child windows are dis-

 

}

 

played.

 

 

 

 

 

The text to appear in the title bar depends on which type of window is currently active. When no window, or an unrecognized window, is active, then the title bar simply includes the version number. The MdiChildActivate event gives no indication of the activating child, so we use the ActiveMdiChild property to retrieve the active Form. We separate the title bar logic into a separate member SetTitleBar, which allows us to call this method from the OnLoad method as well as our event handler.

Compile and run the application to verify that these changes work as expected. The title bar for both parent and child forms is rather similar. Feel free to modify one or the other to make the title bars more unique. If you do this, make sure you consider the behavior of the MainForm class as both an SDI and MDI application.

MDI CHILDREN

555

16.4.5REVISITING THE ACTIVATION EVENTS

Before we leave this section, there is one more additional change required in our program. Take a look at the following OnActivated and OnDeactivate methods from the MainForm class. As we mentioned previously, these events are not received by MDI child forms, so our existing methods will never be called.

protected override void OnDeactivate(EventArgs e)

{

if (ctrlKeyHeld) ReleaseControlKey();

base.OnDeactivate(e);

}

protected override void OnActivated(EventArgs e)

{

// Update toggle toolbar button if required

if (this._dlgPixel == null || _dlgPixel.IsDisposed) AssignPixelToggle(false);

else AssignPixelToggle(_dlgPixel.Visible);

base.OnActivated(e);

}

As you may recall, we overrode the OnDeactivate method in earlier chapters to note that the Ctrl key should be released when the Form is no longer the active application on the desktop. We overrode the OnActivated method as part of the implementation for a toggle toolbar button tied to the PixelDlg form for the window. The deactivate logic is still required, since the Ctrl key is still a part of our MDI application. The pixel toggle button is not included in our current MDI application, so the activation logic is not required here.

For the Ctrl key logic, we can duplicate the deactivation logic in an OnLeave method. This method, you may recall, is invoked when a control, in this case our form, loses focus. A standalone window, such as our SDI application, does not receive this event, so this addition has no effect on our SDI program.

ENSURE THE CTRL KEY IS RELEASED WHEN AN MDI CHILD FORM LOSES FOCUS

 

Action

Result

 

 

 

1

In the MainForm.cs code

protected override void OnLeave(EventArgs e)

 

window, override the OnLeave

{

 

method to duplicate the logic

if (IsMdiChild && ctrlKeyHeld)

 

ReleaseControlKey();

 

from the OnDeactivate

 

 

 

method for the MDI application.

base.OnLeave(e);

 

 

}

 

 

 

556

CHAPTER 16 MULTIPLE DOCUMENT INTERFACES