SDI and MDI Applications


Traditionally, there are three kinds of application that can be programmed for Windows. These are:

  • Dialog-based applications: These present themselves to the user as a single dialog from which all functionality can be reached.

  • Single Document Interfaces (SDI): These present themselves to the user with a menu, one or more toolbars, and one window in which the user can perform some task.

  • Multiple Document Interfaces (MDI): These present themselves to the user in the same manner as an SDI does, but have the ability to hold multiple open windows at a time.

Dialog-based applications are usually small, single-purpose applications aimed at a specific task that needs a minimum of data to be entered by the user or that target a very specific type of data. An example of such an application is shown in Figure 15-10 — the Calculator, which comes with Windows.

image from book Figure 15-10

Single Document Interfaces are usually aimed at solving one specific task, because they allow the user to load a single document into the application to be worked on. This task, however, usually involves a lot of user interaction, and very often users will want the capability to save or load the result of their work. Good examples of SDI applications are WordPad (shown in Figure 15-11) and Paint, both of which come with Windows.

image from book
Figure 15-11

However, only one document can be open at any one time, so if a user wants to open a second document, a fresh instance of the SDI application will be opened and will have no reference to the first instance, so any configuration you do to one instance will not be carried over into the other. Thus, in one instance of Paint, you might set the drawing color to red, and if you open a second instance of Paint, the drawing color will be the default, which is black.

Multiple Document Interfaces are very much the same as SDI applications, except that they are able to hold more than one document open in different windows at any given time. A tell-tale sign of an MDI application is the inclusion of the Windows menu at the right-hand side of the menu bar, just before the Help menu. An example of an MDI application is Adobe Acrobat Reader, shown in Figure 15-12.

image from book
Figure 15-12

A fourth type of application was introduced with Office 2000. This type of application appears to be a cross between an SDI and MDI in that the windows presented to the user do not occupy the same area and each window shows up in the taskbar. Essentially the applications themselves are MDI applications because the main application will not shut down until all the windows are closed, and you can select which open document to view using the Window menu item, but the user interface itself is presented as an SDI.

In this chapter, you focus on the tasks necessary for creating an MDI application. The reasoning behind this is that any SDI application is basically a subset of an MDI, so if you are able to create an MDI you can also create an SDI. In fact in Chapter 16, you create a simple SDI application that will be used to demonstrate how to use the Windows Common Dialogs.

Building MDI Applications

What is involved in creating an MDI? First of all, the task you want the user to be able to accomplish should be one where he or she would want to have multiple documents open at a time. A good example of this is a text editor or, as in the screenshot above, a text viewer. Second, you should provide toolbars for the most commonly used tasks in the application, such as setting the font style, and loading and saving documents. Third, you should provide a menu that includes a Window menu item that allows the user to reposition the open windows relative to each other (tile and cascade) and that presents a list of all open windows. Another feature of MDI applications is that if a window is open and that window contains a menu, that menu should be integrated into the main menu of the application.

An MDI application consists of at least two distinct windows. The first window you create is called an MDI container. A window that can be displayed within that container is called an MDI child. I will refer to the MDI container as the MDI container or main window interchangeably and to the MDI child as the MDI child or child window.

To create an MDI application, you start out in the same way as you do for any other application — by creating a Windows Forms application in Visual Studio. To change the main window of the application from a form to an MDI container you simply set the IsMdiContainer property of the form to true. The background of the form changes color to indicate that it is now merely a background that you should not place visible controls on, although it is possible to do so, and it might even be reasonable to do so under certain circumstances.

To create a child window, add a new form to the project by choosing a Windows Form from the dialog brought up by selecting Project Add New Item. This form becomes a child window when you set the MdiParent property of the child window to a reference to the main window. You cannot set this property through the Properties panel, so you will have to do this using code.

Two things remain before the MDI application is able to display itself in its most basic mode. You must tell the MDI container which windows to display, and then you must display them. You do this simply by creating a new instance of the form you wish to display, and then calling Show() on it. The constructor of the form to display as a child should hook itself up with the parent container. You can arrange this by setting its MdiParent property to the instance of the MDI container.

The following Try It Out is a small example that takes you through these steps, before you move on to more complicated tasks.

Try It Out – Creating an MDI Application

image from book
  1. Create a new Windows application called MdiBasic in the directory C:\BegVCSharp\ Chapter15.

  2. Select the form and set the following properties.

    Property

    Value

    Name

    frmContainer

    IsMdiContainer

    True

    Text

    MDI Basic

    WindowState

    Maximized

    Add a new form to the solution by choosing Add Windows Form from the Project menu. Name the form frmChild.

How It Works

All the code that you need to display a child form is found in the constructors of the form. First, look at the constructor for the child window:

 public frmChild(MdiBasic.frmContainer parent) {    InitializeComponent();     // Set the parent of the form to the container. this.MdiParent = parent; }

To bind a child form to the MDI container, the child must register itself with the container. This is done by setting the form's MdiParent property as shown in the preceding code. You will notice that the constructor you are using includes the parameter parent.

Because C# does not provide default constructors for a class that defines its own constructor, the preceding code prevents you from creating an instance of the form that is not bound to the MDI container.

Finally, you want to display the form. You do so in the constructor of the MDI container:

public frmContainer() {    InitializeComponent();     // Create a new instance of the child form. MdiBasic.frmChild child = new MdiBasic.frmChild(this); // Show the form. child.Show(); }

You create a new instance of the child class and pass this to the constructor, where this represents the current instance of the MDI container class. Then you call Show() on the new instance of the child form and that's it. If you want to show more than one child window, all you have to do is repeat the two highlighted lines in the preceding code for each window.

If you run the code now, you should see something like Figure 15-13 (although the MDI Basic form will initially be maximized, I've resized it here to fit on the page).

image from book
Figure 15-13

It's not the most intriguing user interface ever designed, but it is clearly a solid start. In the next Try It Out, you produce a simple text editor, based on what you have already achieved in this chapter using menus, toolbars, and status bars.

image from book

Try It Out – Creating an MDI Text Editor

image from book

Let's create the basic project first and then discuss what is happening:

  1. Return to the earlier status bar example. Rename the form frmEditor and change its Text property to Editor.

  2. Add a new form with the name frmContainer.cs to the project and set the following properties on it.

    Properties

    Value

    Name

    frmContainer

    IsMdiParent

    True

    Text

    Simple Text Editor

    WindowState

    Maximized

  3. Open the Program.cs file and change the line containing the Run statement in the Main method to:

    Application.Run(new frmContainer());
  4. Change the constructor of the frmEditor form to:

     public frmEditor(frmContainer parent) {    InitializeComponent();           this.toolStripComboBoxFonts.SelectedIndex = 0; // Bind to the parent. this.MdiParent = parent; }
  5. Change the MergeAction property of the menu item with the text &File to Replace and the same property of the item with the text &Format to MatchOnly.

    Change the AllowMerge property of the toolbar to False.

  6. Add a MenuStrip to the frmContainer form. Add a single item to the MenuStrip with the text &File

  7. Change the constructor of the frmContainer form to:

    public frmContainer() {   InitializeComponent();     frmEditor newForm = new frmEditor(this); newForm.Show(); }

    If you run the application now, you will see something like the example shown in Figure 15-14.

    image from book
    Figure 15-14

How It Works

Notice that a bit of magic has happened. The File menu and Help menu appear to have been removed from the frmEditor. If you select the File menu in the container window, you will see that the menu items from the frmEditor dialog can now be found there.

The menus that should be contained on child windows are those that are specific to that window. The File menu should be general for all windows and shouldn't be contained in the child windows as the only place it is found. The reason for this becomes apparent if you close the Editor window — the File menu now contains no items! What you really want is to be able to insert the items in the File menu that are specific to the child window when the child is in focus, and leave the rest of the items to the main window to display.

The properties that are controlling the behavior of menu items are these:

Name

Text

MergeAction

This property specifies how an item should behave when it is to be merged into another menu. The possible values are:

Append: This causes the item to be placed last in the menu.

Insert: Inserts the item immediately before the item that matches the criteria for where this is inserted. This criterion is either the text in the item or an index.

MatchOnly: A match is required, but the item will not be inserted.

Remove: Removes the item that matches the criteria for inserting the item.

Replace: The matched item is replaced and the drop-down items are appended to the incoming item.

MergeIndex

The MergeIndex represents the position of a menu item in regard to other menu items that are being merged. You set this to a value greater than or equal to 0 if you want to control the order of the items that are being merged, otherwise you set it to –1. When merges are being performed, this value is checked and if it is not –1 this is used to match items rather than the text.

AllowMerge

Setting AllowMerge to false means the menus will not be merged.

In the following Try It Out, you continue with your text editor by changing how the menus are merged to reflect which menus belong where.

image from book

Try It Out – Merging Menus

image from book

Follow the steps below to change the text editor to use menus in both the container and child windows.

  1. Add the following four menu items to the File menu on the frmContainer form. Notice the jump in MergeIndex values.

    Name

    Properties

    &New

    Name: ToolStripMenuItemNew
    MergeAction: MatchOnly
    MergeIndex: 0
    ShortcutKeys: Ctrl + N

    &Open

    Name: ToolStripMenuItemOpen
    MergeAction: MatchOnly
    MergeIndex: 1
    ShortcutKeys: Ctrl + O

    -

    MergeAction: MatchOnly
    MergeIndex: 10

    E&xit

    Name: ToolStripMenuItemNewExit
    MergeAction: MatchOnly
    MergeIndex: 11

  2. You need a way to be able to add new windows, so double-click the menu item New and add the code below. It is the same code you entered into the constructor in order for the first dialog to be displayed:

    private void ToolStripMenuItemNew_Click(object sender, EventArgs e) { frmEditor newForm = new frmEditor(this); newForm.Show(); }

  3. Go to the frmEditor form and delete the Open menu item from File menu, then change the properties of the other menu items to the following:

    Name

    Properties

    &File

    MergeAction: MatchOnly
    MergeIndex: -1

    &New

    MergeAction: MatchOnly
    MergeIndex: -1

    -

    MergeAction: Insert
    MergeIndex: 2

    &Save

    MergeAction: Insert
    MergeIndex: 3

    Save &As

    MergeAction: Insert
    MergeIndex: 4

    -

    MergeAction: Insert
    MergeIndex: 5

    &Print

    MergeAction: Insert
    MergeIndex: 6

    Print Preview

    MergeAction: Insert
    MergeIndex: 7

    -

    MergeAction: Insert
    MergeIndex: 8

    E&xit

    Name: ToolStripMenuItemClose
    Text: &Close
    MergeAction: Insert
    MergeIndex: 9

  4. Run the application. You will now see that the two File menus have been merged, but there's still a File menu on the child dialog, containing just one item: New.

How It Works

The items that are set to MatchOnly are not moved between the menus, but in the case of the menu item with the text &File, the fact that the text of the two items matches means that their menu items are merged together.

The Items in the File menus are being merged together based on the MergedIndex properties for the items that you are interested in. The ones that should remain in place have their MergeAction property set to MatchOnly, the rest to Insert.

What is now very interesting is what happens when you click the menu items New and Save menus on the two different menus. Remember that the New menu on the child dialog just clears the text box where the other should create a new dialog. Not too surprisingly, because the two menus should belong to different windows, both work as expected, but what about the Save item? That has been moved off of the dialog and into its parent.

Try to open a few dialogs and enter some text into them, then click Save. Open a new dialog and click open (remember that Save always saves to the same file). Select one of the other windows and click save, then return to the new dialog and click Open again.

What you see is that the Save menu items always follow the dialog that is in focus. Every time a dialog is selected, the menus are merged again.

You just added a bit of code to the New menu item of the File menu in the frmContainer dialog, and you saw that the dialogs are created. One menu that is present in most if not all MDI applications is the Window menu. This lets you arrange the dialogs and often lists them in some way. In the following Try It Out, you will add this menu to your text editor.

image from book

Try It Out – Tracking Windows

image from book

Follow these steps to extend the application with the ability to display all open dialogs and arrange them.

  1. Add a new top-level menu item to the frmContainer menu called &Window. Name this ToolStripMenuItemWindow.

  2. Add the following three menu items to the new menu.

    Name

    Text

    ToolStripMenuItemTile

    &Tile

    ToolStripMenuItemCascasde

    &Cascade

    -

    -

  3. Select the MenuStrip itself, not any of the items that are displayed in it, and change the MDIWindowListItem property to ToolStripMenuItemWindow.

  4. Double-click first the tile item and then the cascade item to add the event handlers and enter the following code:

    private void ToolStripMenuItemTile_Click(object sender, EventArgs e) { LayoutMdi(MdiLayout.TileHorizontal); }     private void ToolStripMenuItemCascasde_Click(object sender, EventArgs e) { LayoutMdi(MdiLayout.Cascade); }

  5. Change the constructor of the frmEditor dialog to this:

     public frmEditor(frmContainer parent, int counter) {   InitializeComponent();       this.ToolStripComboBoxFonts.SelectedIndex = 0;       // Bind to the parent.   this.MdiParent = parent; this.Text = "Editor " + counter.ToString(); }
  6. Add a private member variable to the top of the code for frmContainer and change the constructor and the event handler for the menu item New to the following:

    public partial class frmContainer : Form { private int mCounter;       public frmContainer()   {     InitializeComponent();     mCounter = 1; frmEditor newForm = new frmEditor(this, mCounter);     newForm.Show();   }       private void ToolStripMenuItemNew_Click(object sender, EventArgs e)   { frmEditor newForm = new frmEditor(this, ++mCounter);     newForm.Show();   }

How It Works

The most interesting part of this example concerns the Window menu. To have a menu display a list of all the dialogs that are opened in a MDI application, all you have to do is create a menu at the top level for it and set the MdiWindowListItem property to point to that menu.

The Framework will then append a menu item to the menu for each of the dialogs that are currently displayed. The item that represents the current dialog will have a check mark next to it, and you can select another dialog by clicking the list.

The other two menu items, the Tile and Cascade items, demonstrated a method of the form: MdiLayout. This method allows you to arrange the dialogs in a standard manner.

The changes to the constructors and New item simply ensure that the dialogs are numbered.

If you run the application now, you should see something like Figure 15-15.

image from book
Figure 15-15

image from book




Beginning Visual C# 2005
Beginning Visual C#supAND#174;/sup 2005
ISBN: B000N7ETVG
EAN: N/A
Year: 2005
Pages: 278

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net