1. Trang chủ
  2. » Công Nghệ Thông Tin

Manning Windows Forms Programming (phần 12) pdf

50 309 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 50
Dung lượng 1,95 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

private bool UpdateAlbumName string newName, object obj { ListViewItem item = obj as ListViewItem; TreeNode node = obj as TreeNode; // Determine the file name string fileName = null;

Trang 1

As we mentioned at the start of this section, we will not spend much time discussingthese changes, since they leverage concepts and features we have seen before Let’smove on to editing a tree node’s label.

15.5.2 SUPPORTING LABEL EDITS

Tree nodes can be edited in a manner similar to list items There is a BeginEdit

method in the TreeNode class to initiate a label edit programmatically, and eLabelEdit and AfterLabelEdit events in the TreeView class that occur beforeand after the user edits the label Event handlers for these events receive the NodeLa- belEditEventArgs class for the event parameter This class is summarized in.NET Table 15.5, and is manipulated in much the same way as we saw for the

Befor-LabelEditEventArgs class when handling label events for the ListView class

5 Update the AfterSelect event

handler to use the new

DisplayPhoto method to ensure the proper control is visible.

private void treeViewMain_AfterSelect( .) {

.

if (node.Parent == null) {

// Bad tag or top-level node.

LoadAlbumData(fileName);

DisplayPhoto(null);

} else if (Path.GetExtension(fileName) ) {

// Album node selected PhotoAlbum album = OpenTreeAlbum( .); LoadPhotoData(album);

DisplayPhoto(null);

} else // must be a photograph {

// Clear the list and display the photo listViewMain.Clear();

DisplayPhoto(node);

} }

6 Add a Resize event handler for

the PictureBox control to force the control to redraw the entire image when it is resized.

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

// Force the entire control to repaint pictureBoxMain.Invalidate();

}

Trang 2

F UN WITH TREE VIEWS 517

In our application, we will permit nodes to be edited using the menuEditLabel

menu item, or by pressing the F2 key when a tree node is selected and the tree viewhas the focus The following table details the steps required for this change:

.NET Table 15.5 NodeLabelEditEventArgs class

The NodeLabelEditEventArgs class represents the event data associated with the eLabelEdit and AfterLabelEdit events in the TreeView class This class is part of the

Befor-System.Windows.Forms namespace, and inherits from the System.EventArgs class.

Public Properties

CancelEdit Gets or sets whether the edit operation should

be cancelled This property can be set both before and after the node is edited.

Label Gets the new text to assign to the label of the

indicated node.

Node Gets the TreeNode object being edited.

S UPPORT EDITING OF TREE NODE LABELS

1 Set the LabelEdit property for

the TreeView control to true

in the MainForm.cs [Design]

window.

Tree node labels may now be edited.

2 Handle the KeyDown event for

the TreeView control to initiate

a label edit when the F2 key is pressed in the tree control.

private void treeViewMain_KeyDown (object sender, System.Windows.

Forms.KeyEventArgs e) {

if (e.KeyCode == Keys.F2) {

if (treeViewMain.SelectedNode != null) {

treeViewMain.SelectedNode.BeginEdit(); e.Handled = true;

} } }

3 Update the menuEdit_Popup

event handler to use the text

“Node” for the

menuEditLabel menu when the TreeView has the focus.

if (treeViewMain.Focused)

{ menuEditLabel.Enabled = (treeViewMain.SelectedNode != null); menuEditLabel.Text = "&Node";

} else // assume ListView has focus {

menuEditLabel.Enabled = (listViewMain.SelectedItems.Count > 0);

if (this._albumsShown) menuEditLabel.Text = "&Name";

else menuEditLabel.Text = "&Caption";

}

}

Trang 3

4 Update the

menuEdit-Label_Click event handler to edit the appropriate item based

on the current focus.

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

if (treeViewMain.Focused)

{

if (treeViewMain.SelectedNode != null) treeViewMain.SelectedNode.BeginEdit(); }

else if (listViewMain.SelectedItems.Count > 0)

listViewMain.SelectedItems[0].BeginEdit(); }

5 Handle the AfterLabelEdit

event for the TreeView control.

Note: We permit the user to

edit the root node here to alter

a top-level name in the tree, even though this change is dis- carded when the application exits A more robust solution might be to prevent this from occurring, or to save the change in a configuration file.

private void treeViewMain_AfterLabelEdit (object sender, System.Windows.

Forms.NodeLabelEditEventArgs e) {

if (e.Label == null) {

// Edit cancelled by the user e.CancelEdit = true;

return;

}

// No changes required for root node

if (e.Node.Parent == null) return;

string fileName = e.Node.Tag as string;

if (Path.GetExtension(fileName) == ".abm") e.CancelEdit = !UpdateAlbumName(e.Label, e.Node); else

e.CancelEdit = !UpdatePhotoCaption(e.Label, e.Node); }

6 Rewrite the

UpdateAlbum-Name method to accommodate both list items and tree nodes.

private bool UpdateAlbumName

(string newName, object obj)

{ ListViewItem item = obj as ListViewItem; TreeNode node = obj as TreeNode;

// Determine the file name string fileName = null;

if (item != null) {

fileName = item.Tag as string;

node = FindNode(fileName, false);

} else if (node != null) fileName = node.Tag as string;

Note: Recall that the list view’s AfterLabelEdit

event handler from chapter 14 provides a Item object when calling this method This invocation

ListView-is still valid and ListView-is properly dealt with by thListView-is code.

c Determine the file name for the appropriate object.

d If the object is a list view item, also find the node cor- responding to this item.

Trang 4

F UN WITH TREE VIEWS 519

7 Rename the file.

newFileName = RenameFile(fileName, newName, ".abm"); }

if (newFileName == null) {

MessageBox.Show("Unable to rename album " + "to this name.");

return false;

}

8 Update the Tag property for the

appropriate object.

Note: When the object is a list

item, this updates the sponding node as well.

// Update the appropriate Tag property

if (item != null) {

item.Tag = newFileName;

if (node != null) node.Text = newName;

} else if (node != null) node.Tag = newFileName;

return true;

}

9 Rewrite the

UpdatePhoto-Caption method to modate both list items and tree nodes.

private bool UpdatePhotoCaption

(string caption, object obj)

{ ListViewItem item = obj as ListViewItem; TreeNode node = obj as TreeNode;

// Determine the album index int index = -1;

if ((item != null) && (item.Tag is int)) {

index = (int)item.Tag;

node = FindNode(_album[index].FileName, false);

} else if (node != null) {

param-b Convert the given object

to both a list item and a tree node.

c Determine the album index for the appropriate object.

d If the object is a list view item, also find the node corresponding to this item.

Trang 5

Our program now permits editing of nodes in the TreeView and items in the View Editing is initiated with the menuLabelEdit menu or the F2 key, and isbased on which control currently has the focus.

List-In both update methods, note how the as keyword is used to convert the givenobject into both a TreeView and a ListView, as is shown in the following excerpt.The remainder of each method executes the appropriate statements based on whichtype of control is provided

ListViewItem item = obj as ListViewItem;

TreeNode node = obj as TreeNode;

Also of note is our use of the FindNode method created earlier in the chapter as part

of section 15.4.2 As you may recall, we included a parameter to this method thatindicated whether to expand the selected node We set this second parameter to

false here to ensure that the contents of the tree view control are not altered.Our final change is to support the display of our album and photograph propertydialogs from the TreeView control

In chapter 14 we created a Properties menu We handled the Click event for thismenu in a menuProperties_Click method, and created the DisplayAlbumProp- erties and DisplayPhotoProperties methods to display the two types of dialogsrequired Here we would like to change the behavior of this menu to the following:

When the TreeView has the focus, display the appropriate properties dialog if

an album node or a photograph node is selected

When the ListView has the focus, display the appropriate properties dialogfor the selected item

When the PictureBox has the focus, display the photograph properties log associated with the displayed image

dia-To make this change, we will modify our Display methods to accept either a ViewItem or a TreeNode object The following table details the changes required

List-11 Update the photograph’s

caption, and save the changes

to the album.

Note: When the object is a list

item, this updates the sponding node as well.

// Update caption _album[index].Caption = caption;

if (item != null && node != null) {

// Update node text as well node.Text = caption;

Trang 6

F UN WITH TREE VIEWS 521

U PDATE P ROPERTIES MENU TO HANDLE TREE NODES

1 In the MainForm.cs code

window, update the

menuProperties_Click event handler to accommodate the three controls that might have the focus.

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

if (treeViewMain.Focused) {

TreeNode node = treeViewMain.SelectedNode; string file = node.Tag as string;

if (node == null || node.Parent == null || file == null)

return; // do nothing

if (Path.GetExtension(file) == ".abm") DisplayAlbumProperties(node);

else DisplayPhotoProperties(node);

} else if (pictureBoxMain.Focused) {

// Display photograph for this image TreeNode node = treeViewMain.SelectedNode;

if (node != null) DisplayPhotoProperties(node);

} else

if (listViewMain.SelectedItems.Count > 0) {

ListViewItem item = listViewMain.SelectedItems[0];

if (this._albumsShown) DisplayAlbumProperties(item);

else DisplayPhotoProperties(item);

} }

2 Rewrite the

DisplayAlbum-Properties method to accept

an object instance.

private void DisplayAlbumProperties

(object obj)

{ ListViewItem item = obj as ListViewItem; TreeNode node = obj as TreeNode;

// Open the album as appropriate PhotoAlbum album = null;

if (item != null) {

string fileName = item.Tag as string;

if (fileName != null) album = this.OpenAlbum(fileName); }

else if (node != null) {

album = OpenTreeAlbum(node);

}

if (album == null) // as in chapter 14

How-to

a For the TreeView control, ignore the parent node and call the appropriate Proper- ties method based on the node type.

b For the PictureBox control, call the DisplayPhoto- Properties method on the selected photo node.

c For the ListView control, the code is the same as in chapter 14.

Trang 7

3 When displaying the album edit

dialog, only update the list item settings if the given item is a list view item.

Note: If the given item is a tree

node, then photographs are played in the list view, and these settings should not be updated.

using (AlbumEditDlg dlg = new AlbumEditDlg(album)) {

if (dlg.ShowDialog() == DialogResult.OK) {

// Save changes made by the user

// Update item settings

if (item != null) {

item.SubItems[MainForm.

AlbumTitleColumn].Text = album.Title;

bool hasPwd = (album.Password != null) && (album.Password.Length > 0); item.SubItems[MainForm.

AlbumPwdColumn].Text = (hasPwd ? "y" : "n");

} } }

Trang 8

F UN WITH TREE VIEWS 523

As you can see, the display methods use the as keyword to convert a given object

into both a ListViewItem and a TreeNode instance Whichever instance is

non-null indicates how to display the property dialog

TRY IT! As a further change to our TreeView control, add a context menu to this

control to perform the following tasks

1 An “Add Directory” menu item that permits a new album directory to

be added to the tree This should prompt for a directory name and add

a top-level node to the tree for each album discovered in that directory

2 A “Properties” menu item that displays the properties dialog for thenearest node This should select the nearby node, and then call the

PerformClick method for the menuProperties menu

3 A “Delete” menu item that deletes a node from the tree This shoulddelete the album file from the file system or the Photograph from thecontaining album for the given node You should prompt the user tomake sure they really wish to do this

You will need to use the GetNodeAtmethod to locate the TreeNodeinstance at agiven pixel position, so that the action applies to the specific tree node located at thecurrent mouse position

5 After displaying the dialog,

update the list or node with any modified photograph settings.

Note: Recall that our photo edit

dialog permits all photographs

in an album to be updated As a result, when the photographs are shown in the tree node, the label for each related node must

be updated as well This is true regardless of the type object

given.

using (PhotoEditDlg dlg = new PhotoEditDlg(_album)) {

if (dlg.ShowDialog() == DialogResult.OK) {

// Save any changes made

// Update controls with new settings TreeNode baseNode = null;

if (item != null) {

LoadPhotoData(_album);

baseNode = treeViewMain.SelectedNode; }

else if (node != null) {

baseNode = node.Parent;

}

if (baseNode != null) {

// Update all child labels foreach (TreeNode n in baseNode.Nodes) {

n.Text = _album[n.Index].Caption; }

} } } }

U PDATE P ROPERTIES MENU TO HANDLE TREE NODES (continued)

Trang 9

You could also implement these items within the ListViewcontrol as well.This completes our discussion on the TreeViewclass Before we move on, let’s do aquick recap of what we covered in this chapter.

15.6 R ECAP

In this chapter we extended the MyAlbumExplorer project built in chapter 14 to add

a TreeView control We divided our main window using the Splitter class inorder to create a classic explorer window such as that used in the Windows operatingsystem for browsing the file system

A tree view contains a hierarchy of TreeNodeobjects, and we created a tree playing our album files and the photos in each album We discussed common oper-ations within a tree view such as expand, collapse, selection, and label editing Duringthe course of the chapter, the ListViewand TreeViewcontrols were integrated todisplay a common interface, with changes to one control reflected in the other control

dis-We also added a PictureBoxcontrol in order to display the image associated with

a selected photograph node in the tree

The explorer interface we saw in these last two chapters is one of three kinds ofstandard Windows interfaces In part 2 of this book we built what is called a singledocument interface In the next chapter we will look at another kind of interface,namely the multiple document interface

Trang 10

The ListView and TreeView classes discussed in chapters 14 and 15 present a lection of objects within a single list or tree control These are especially useful whencreating an explorer-style interface such as our MyAlbumExplorer application, or thecommon Windows Explorer application Another kind of interface is the multiple

col-document interface, also called an MDI (normally pronounced em-dee-eye).

An MDI application presents a collection of forms within a single applicationwindow We will discuss MDI applications through the following discussion areas:

Understanding various interface styles

Creating an MDI container window

Converting an SDI application into an MDI application

Using MDI-related class members of various controls

Merging two menus into a single merged menu

Managing menus and forms in an MDI application

These topics will be covered as we progress through the chapter, beginning with theconcept of interface styles

Trang 11

16.1 I NTERFACE STYLES

Before we discuss exactly how multiple document interfaces are created, let’s take astep back and consider the various types of application interfaces used for Windowsapplications Most Windows applications fall into one of three interface categories:

Single document interfaces

Explorer interfaces

Multiple document interfaces

We will discuss each type of interface separately

A single document interface, also called an SDI, is an interface that displays a singledocument or other encapsulated data within a single form Our MyPhotos applica-tion, as shown in figure 16.1, is a good example of this style, in which a single photoalbum is displayed The user can look at multiple photo albums only by examiningone after another The contents of two albums cannot be compared unless two copies

of the program are running

In the Windows operation system, the Notepad and WordPad applications vide additional examples of the SDI style

pro-16.1.2 EXPLORER INTERFACES

The MyAlbumExplorer application built in chapters 14 and 15 is an example of anexplorer interface, and can be seen in figure 16.2 In this style, a hierarchy of informa-tion is presented to the user Normally a TreeView control displays this hierarchy,typically on the left, with details on the selected node provided in a ListView con-trol Sometimes the TreeView control can be hidden, and sometimes it is always

Figure 16.1 Our single document interface displays one photo album at a time.

Trang 12

I NTERFACE STYLES 527

present Alternate information may appear on the list side of the window as well, such

as the photographic image we displayed in chapter 15 for a selected photograph inthe MyAlbumExplorer application

In Windows, of course, the Windows Explorer application is another example ofthis style

A multiple document interface (MDI) allows multiple views of one or more ments or other encapsulated data to be displayed at the same type This permits alter-nate views of the same data, or separate presentations of the same style of data, within

docu-a single window For exdocu-ample, docu-a stock mdocu-arket MDI docu-applicdocu-ation might present ent historical or graphical views of a single portfolio, each as a separate window Alter-nately, such an application might present multiple portfolios, each as its own windowwithin a containing application window

differ-In the original conception of this style, a single window acted as a container forother windows, where each contained window displayed a specific instance or view of

a type of data More recently, well-known MDI applications such as Microsoft Wordand Excel have taken the approach of displaying all of their windows directly on thedesktop, each within a separate application window, while still preserving an MDIlook and feel from the menu bar and other parts of the interface This relatively newstyle, the Multiple Single Document Interface, or MSDI, is consistent with the man-ner in which Web browsers have typically worked While an MSDI interface can becreated in Visual Studio.NET, it is not necessarily an easy task

Figure 16.2 Our explorer interface presents the collection of photo albums in list form.

Trang 13

Also note that Visual Studio NET, while providing an MDI-like interface, usesmore of a TabControl look and feel for the set of displayed windows, or what might

be called a Multiple Tabbed Documents Interface, or MTDI In this style, multiplesets of windows are displayed as horizontal or vertical groups of tabs Both the MSDIand MTDI approaches can be created using the NET Framework as an alternative tothe traditional MDI interface, although there is not really any direct support for thesenewer interfaces As a result, implementing such interfaces requires much more effortfrom the developer

For our purposes, a traditional MDI application provides the means to discussand demonstrate the manner in which the NET Framework supports such applica-tions We will convert the existing MyPhotos application into the MDI applicationshown in figure 16.3 As you can see, this application will incorporate the Form classes

we have created in part 2 of this book

The reuse of our existing classes is possible because of the manner in which the Form

class in general and MDI support in particular is integrated into the Windows Formshierarchy As we discussed in chapter 7, a Form object is a Control instance thathappens to display an application window For MDI applications, Form controls arecontained by a parent Form Of course, the contained forms can be resized andmoved within their container, and can still display menus, toolbars, status bars, andother controls As we shall see, the relationship between MDI parent and child forms

is different than the relationship between control containers and controls

Figure 16.3 Our multiple document interface, created in this chapter, displays a

se-lected set of photo albums within a single window.

Trang 14

I NTERFACE STYLES 529

To provide some insight and perhaps some perspective on MDI applications, the lowing table lists a number of class members specific to the implementation of MDIapplications in the NET Framework Of course, these members can be used forother purposes, and additional properties, methods, and events are certainly used inMDI applications These events highlight many of the MDI-specific tasks that areoften performed in this style interface The table provides a short description of eachmember and a reference to the section in this chapter where more information oneach item may be found

fol-Class members often used in MDI applications

Class Member

type Member name Description

See section

MdiChildren Gets the set of MDI children contained by

this form as an array of Form objects.

16.4.3

MdiParent Gets or sets the MDI container for this form

If set, then this form is an MDI child form.

16.2.2

MergedMenu Gets the MainMenu object representing the

current merged menu for an MDI container form.

16.3

Methods LayoutMdi Arranges the MDI children within this form

using a given layout style.

16.5.1

Events MdiChildActivate Occurs when an MDI child form is activated

or deactivated within an MDI application

Note that MDI children do not receive the

Activated and Deactivate events.

16.4.4

Menu

Properties MdiListItem Gets the MenuItem object contained by this

menu that displays a list of MDI child forms for the associated form object.

16.5.2

Methods MergeMenu Merges the MenuItem objects in a given

menu with those contained by this menu.

16.3

MenuItem

Properties MdiList Gets or sets whether this menu should be

populated with a list of MDI child forms contained by the associated form.

16.5.2

MergeOrder Gets or sets the relative position of this menu

item when it is merged with another menu.

16.3.2

MergeType Gets or sets how this menu should be

merged with other menus The default is

MergeType.Add

16.3.1

Trang 15

Also note that the behaviors of desktop-related actions within an MDI child form aremodified For example, the Minimize and Maximize buttons on the title bar workwithin the parent window, rather than on the desktop itself.

In the rest of this chapter we will enhance our MyPhotos application to support

a multiple document interface We begin with the MDI container form

16.2 MDI FORMS

So let’s convert our existing MyPhotos application into an MDI application This tial work is not as difficult as you might think Generally, we need one Form to act asthe top-level container, and the ability to create other forms as children within thiscontainer Here, we will do this via the following tasks:

ini-1 Create a new parent form for the application to act as the MDI container

2 Add a menu bar and New menu item to create MDI child forms

3 Define a new Main method in the parent as the entry point for the application

Of course, there will be other work to perform to clean up the behavior of our cation These steps will get us going, and subsequent sections will deal with otherrequired changes Figure 16.4 shows how our application will look by the end of thissection Note in particular the two File menus We will address this issue in the nextsection while discussing Merged Menus

appli-Figure 16.4 Note the two File menus for this window The menus from both

our ParentForm and MainForm classes appear separately on the menu bar We

will address this in section 16.3.

Trang 16

MDI FORMS 531

The creation of an MDI container form is much like the creation of any other form.Such a form is often referred to as a parent form, since it acts as the parent for one ormore MDI child forms The following table details the steps required for this task

Set the version number of the MyPhotos application to 16.2.

As you can see, the contents of the window appear in a darker color and includes a

3-D border to indicate that this form is now an M3-DI container This color is the tem.AppWorkspacecolor, which is typically a darker version of the System.Con- trol color This background is a hidden MdiClient control, and cannot bemanipulated in code as it is not exposed by the Form class This background containsthe MDI child forms, and is always last in the z-order As a result, any controls added

Sys-to the form will appear above this background, and therefore in front of any MDIchildren Typically, controls added to an MDI container are docked to one edge ofthe parent form

The code generated for our ParentForm class is much like other forms we haveseen in this book The InitializeComponent method generated by Visual Studio.NET is as follows:

private void InitializeComponent()

{

//

// ParentForm

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(592, 373);

C REATE A NEW FORM AS AN MDI CONTAINER

1 In the Solution Explorer window,

add a new Windows Form to the application called ParentForm

The new file appears in the Solution Explorer window and the ParentForm.cs [Design] window is displayed.

2 Set the icon property for the

form to the “icons/Writing/

BOOKS04.ICO” file in the common image directory.

3 Set the IsMdiContainer

property to true

Note: This establishes the form

as an MDI container form.

4 Set the Size property to

600×400 pixels.

Trang 17

this.Name = “ParentForm”;

this.Text = “ParentForm”;

}

With the parent form created, we can turn our attention to the child form

With our MDI container in place, we can add the infrastructure required for ing MDI child forms This will consist of a menu bar and a New menu item Fortu-nately, we already have our MainForm class available to act as the child form.The following table shows how to create a child form in our application As part

generat-of this task, we will add an Exit menu as well

A DD ABILITY TO CREATE CHILD FORMS

1 Add a MainMenu object to the ParentForm

class in the ParentForm.cs [Design] window.

2 Add a top-level File menu containing the

three menu items as shown.

3 Add a Click event handler for the Exit

menu to close the form.

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

Settings Menu Property Value

File (Name) menuFile

Text &File New (Name) menuNew

Shortcut CtrlN Text &New

separator

Exit (Name) menuExit

Text E&xit

Trang 18

One quite simple means to fix our entry point would be to modify the Main method

in the MainForm class directly The new code would look as follows, with the changehighlighted in bold:

public class MainForm : System.Windows.Forms.Form

ParentForm class, and modify the project to use this new method as the entry point.The following table creates a new entry point within the ParentForm class

5 Within this handler, create a MainForm

object as an MDI child form.

MainForm newChild = new MainForm(); newChild.MdiParent = this;

a Create a new MainForm object.

b Define this form as an MDI child by ting the current form as its MDI parent.

set-c Display the child form using the Show

method.

Trang 19

The application is now ready The startup object specified here is used by the C#compiler to establish the entry point for the application, and is only required if thereare multiple Main methods in your project On the command-line, the C# compileraccepts the /main switch to specify the class containing the Main method to use asthe application’s entry point.

Run the application to verify that the ParentForm window appears and the Newmenu can be used to create MainForm objects as child windows If you explore this newapplication, you will find some rather peculiar behavior for some of the controls Wewill discuss and address these issues throughout the remainder of this chapter

TRY IT! Of course, the MyPhotos Property Pages dialog used in step 2 can also be

used to set the Startup Object to the MyPhotos.MainForm class Whenthis is done, the application displays the familiar single document interfacecreated in part 2 of this book Make this change and run the application toobserve this behavior

Among the odd features you may notice in the MDI version of this application is themenu bar In particular, there are two File menus when a MainForm window is dis-played Adjusting this behavior is our next topic

C REATE AN ENTRY POINT IN THE PARENT FORM

1 Create a Main method in the

ParentForm.cs code window to serve as the entry point for our MDI application.

Note: If you compile the

applica-tion after this step, you will get an error indicating that the program defines more than one entry point.

2 Set the Startup Object for the

MyPhotos project to the

associ-c Select the Form class.

Trang 20

MyPhotos.Parent-M ERGED MENUS 535

16.3 M ERGED MENUS

By definition, an MDI application permits multiple windows to be displayed Eachchild window may be the same or different, and each may display different informa-tion about one or more objects It would be nice if the menu items for the applicationcould be customized depending on which child window is displayed Exactly how to

do this is the subject of this section

As an example, consider a car-buying application that permits users to search for,display, and purchase used cars As an MDI application, this might display a photo-graph of the car in one window, standard features and warranty information inanother window, and optional packages and pricing information in a third window.Clearly the set of menus and the contents of each menu should differ depending onwhich style window is currently active For instance, menus for the photograph win-dow might permit different colors to be viewed or different parts of the vehicle to beshown These concepts make no sense for the other windows, and should not be acces-sible when these windows are active

While our application is not quite so ambitious, we do have the problem of ourFile menu, since both the ParentForm and the MainForm class contain this item.Once we make the two File menus merge, we also have to deal with the contents ofthese menus, to ensure the items appear in an appropriate order

The Menu class provides a MergeMenumethod for merging two menus together.This method accepts a Menu object and merges it with the calling Menuobject The

MenuItem class provides additional overrides of this method to merge MenuItem

objects and to copy a menu item so that it may be merged with other menus This ter method has the advantage of not affecting the existing MenuItemobject

lat-In MDI applications, an MDI container form automatically merges the menu forthe active child form with the MainMenuobject stored in its Menu property The

Form.MergedMenuproperty contains the result of this merge, and can be used toaccess or modify the merged menu directly The Form.Menuproperty always containsthe original menu assigned to the form

Since this merging occurs automatically for MDI applications, this section willfocus on how menus are merged together, and make the appropriate changes in ourMDI application to merge the two File menus together First we will discuss the var-ious ways to merge two menus, followed by the mechanism for establishing the order

of merged menu items

As mentioned at the start of this chapter, the MenuItem class contains two propertiesthat control exactly how two menus are merged together This section will discuss the

MergeType property that controls how the menus are merged Later we will look atthe MergeOrder property that controls the final position of a merged item

Trang 21

The MergeTypeproperty gets or sets a MenuMergeenumeration value ing how this menu should be merged with other menus An overview of this enumer-ation appears in NET Table 16.1 The default setting for the MergeTypeproperty

specify-is MenuMerge.Add This default adds each item separately, and is the cause of the twoFile menus in our current application

This explains why our existing application has two File menus Since the MergeType

property defaults to Add, the menus are simply added to the collection separately

We can fix this by modifying the MergeType property for these menus

Set the version number of the MyPhotos application to 16.3.

Compile and run the application, and open a client form in the parent window to seethe merged menu as shown in the table The two menus are merged, but their contents

.NET Table 16.1 MenuMerge enumeration

The MenuMerge enumeration specifies various types of behavior for a MenuItem object when it is merged with another menu This enumeration is used by the MergeType property

in the MenuItem class, and is part of the System.Windows.Forms namespace.

Enumeration Values

Add The item is added to the collection of MenuItem

objects in the merged menu.

MergeItems All MenuItem objects contained by the item are

merged with those contained by the menu at the same position in the merged menu.

Remove The item is not included in the merged menu Replace The item replaces an existing MenuItem object

at the same position in the merged menu.

M ERGE THE PARENT AND CHILD F ILE MENUS

1 In the MainForm.cs [Design]

window, set the MergeType

property of the File menu item

to MergeItems

The two File menus in the parent and child form will now merge into a single menu in the application, the result of which is shown in this graphic The menu items exhibit the default merge behavior, which is Add

2 Similarly, set the MergeType

property to MergeItems for the File menu in the ParentForm.cs [Design] window.

Note: The MergeType property must be set for both File menu objects to merge the two menus together.

Trang 22

We can fix this, of course, but first a brief aside.

TRY IT! Modify the MergeType property for either File menu so that one menu

uses the MergeItems member value and the other the Add value Run theapplication to verify that the menus no longer merge

Also rename the File menu in the ParentForm class to use the name

“Fickle.” Run the application and see which name is shown in the tion You will find that the name in the MDI child is preferred over thename in the parent This is a consequence of how the menus are merged,and can be utilized to rename a menu in the parent form when a specifickind of child is displayed

applica-Back in our application, we have two problems with the merged File menu The first

is that we have two versions of the New and Exit menus, and the second is that theorder of the merged menu is a bit of a mess

We will address these two problems together as part of a discussion on the Orderproperty

So far we have merged our two File menus into a single menu The next step is toclean up the contents of this menu This involves setting the appropriate MergeType

for each menu, and using the MergeOrder property to establish the order of theseitems within the merged menu The MergeOrder property contains the zero-basedposition where the menu should appear within the merged menu If multiple itemsare assigned the same order, they appear one after another in the merged menu This

is the case in our existing code, where all menus in the File menu use the default

MergeOrder value of zero

Before we start making changes to our existing menus, let’s step back and considerwhat a reasonable File menu should contain for our MDI application Such a menu

is described by the following table, which shows the menu name, its position, a shortdescription, and some implementation notes

Contents of the merged File menu in our MDI application

Menu name Position Description Implementation Notes

New 0 Opens a new album in a new MDI

child window.

Same as existing New menu in the

ParentForm class.

Open 1 Opens an existing album file in a

new MDI child window.

This should be processed by the

ParentForm class in order to create the new child window.

Trang 23

This details how the merged menu should look There is still the question of themenu structure in the ParentForm and MainForm classes Based on the previoustable, we can establish how the File menu should appear for each Form class The fol-lowing table details the contents of each menu, and describes its behavior in themerged menu object.

We are now ready to update our menus based on these tables Our first change willsimply update the menus so that they appear as described within the application

Close 2 Closes the active MDI child

child window under a new name.

Same as existing Save As menu in the MainForm class.

separator 6

Exit 7 Closes all child windows as well as

the MDI container form.

Same as existing Exit menu in the

ParentForm class.

Individual File menu for our MDI parent and child classes

Class Menu Implementation notes

ParentForm

New This menu should behave as it already does, and replace the New menu

in the child form.

Open This is a new menu to open an existing album in a new window.

separator This menu should not exist when the menus are merged.

Exit This menu should behave as it already does, and appear at position 7

when the menus are merged.

Save As As currently exists, at position 5 in the merged menu.

separator Should become the second separator at position 6 in the merged menu Exit Should become the Close menu at position 2 in the merged menu.

Contents of the merged File menu in our MDI application (continued)

Menu name Position Description Implementation Notes

Trang 24

M ERGED MENUS 539

Once this is done, we will look at implementing any changes required to supportthese menus

The following table details the steps required:

The key points here are the fact that the New and Open menus in the ParentForm

class replace those in the MainForm class, and the merge order for each menu mustmatch the desired position we discussed earlier One other interesting point is thereuse of the Exit menu in the MainFormclass for the Close menu in the mergedmenu This makes sense, although we still need to rename the menu text to read

A SSIGN THE TYPE AND ORDER FOR OUR F ILE MENUS

1 In the ParentForm.cs [Design]

window, add an Open menu to the File menu just after the existing New menu.

2 Update the merge settings for the

items in the File menu.

3 In the File menu for the MainForm.cs

[Design] window, update the merge settings for the items in this menu.

Settings Property Value

(Name) menuOpen Shortcut CtrlO Text &Open

Settings Menu MergeType MergeOrder

New Replace 0 Open Replace 1

separator Remove 0 Exit Add 7

Settings

Menu MergeType MergeOrder

New Remove 0 Open Remove 1 separator Add 3 Save Add 4 Save As Add 5 separator Add 6 Exit Add 2

Trang 25

“Close” rather than “Exit.” We will do this in a way that continues to preserve theSDI application from part 2.

This change ensures that the Exit menu displays “Close” when the MainForm object iscreated as an MDI child window Otherwise, the default setting of “Exit” will be used.Compile and run the application to verify that our changes produce the appro-priate menu structure Create a new MDI child window and display the File menu.Your application should appear as in figure 16.5 Note how all the menus are now inthe desired order, including the separator menus Also note that the Exit menu fromthe MainForm class is reincarnated as the Close menu in the MDI application

C HANGE THE E XIT MENU TEXT WHEN RUNNING AS AN MDI CHILD FORM

4 Override the OnLoad method in

the MainForm.cs code window.

protected override void OnLoad(EventArgs e) {

5 If the form is an MDI child

window, then modify the Exit menu to appear as a Close menu.

How-to

Use the IsMdiChild property.

if (IsMdiChild) menuExit.Text = "&Close";

base.OnLoad(e);

}

Figure 16.5 The merged File menu here gives no indication that different

menu items are processed in different classes.

Ngày đăng: 07/07/2014, 04:20

TỪ KHÓA LIÊN QUAN