Demonstration
The remainder of this article walks you through a demonstration program that shows just how easy it is to implement a useful MDI program by using the .NET Framework’s tools. The application is a text editor that permits you to have multiple documents open. It’s rather basic, implementing a bare minimum of commands including cut, copy, and paste. Here are the steps to follow:
- Create a new Visual Basic Windows application.
- With the initial form, change the IsMdiContainer property to True and the Text property to MDI Parent.
- Add a new Windows form to the project, specifying Document as the form name.
- Add a RichTextBox to the document form, and set its Dock property to Fill.
- Add a MenuStrip control to the parent form, and add File, Edit, and Window menu items to the MenuStrip.
- Set the MenuStrip’s MdiWindowListItem property to the Window menu item.
- Add New, Open, Save, Close, and Exit subitems to the File menu.
- Add Cut, Copy, and Paste subitems to the Edit menu.
- Add Tile Horizontally, Tile Vertically, and Cascade subitems to the Window menu.
- Add an OpenFileDialog control and a SaveFileDialog control to the parent form.
The next step is to add the code. Most of the code goes in the parent form; Listing 1 shows this code. Listing 2 shows the small amount of code for the document form. (The source.zip file contains all of the code to make it easier to use.)
Listing 1 Code in the text editor’s parent form.
Imports System.IO Public Class Form1 ’ Keep count of new documents created. Private NewChildCount As Integer = 0 ’************************************ ’ These event procedures deal with opening, saving, creating, ’ and closing documents. Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveToolStripMenuItem.Click Dim currentDoc As Document = Me.ActiveMdiChild If Not currentDoc Is Nothing Then If currentDoc.isNamed Then SaveDocument(currentDoc, currentDoc.Text) Else ’ No name assigned yet. SaveFileDialog1.Filter = "Text files *.txt | *.txt" SaveFileDialog1.FileName = currentDoc.Text & ".txt" If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then SaveDocument(currentDoc, SaveFileDialog1.FileName) End If End If End If End Sub Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click ’ File, Open menu command. Dim sr As StreamReader OpenFileDialog1.FileName = "" OpenFileDialog1.Filter = "Text Files *.txt | *.txt" If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then Try sr = File.OpenText(OpenFileDialog1.FileName) Dim newDoc As New Document() newDoc.RichTextBox1.Text = sr.ReadToEnd sr.Close() newDoc.Text = OpenFileDialog1.FileName newDoc.MdiParent = Me newDoc.Show() newDoc.isNamed = True ’ Move cursor to the start of the document. With newDoc.RichTextBox1 .Select() .SelectionStart = 0 .SelectionLength = 0 End With Catch ex As Exception MsgBox("There was an error opening the file.") End Try End If End Sub Private Sub NewToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewToolStripMenuItem.Click ’ File, New command NewChildCount += 1 Dim NewChild As New Document() NewChild.MdiParent = Me NewChild.Text = "Document " & NewChildCount.ToString NewChild.Show() End Sub Private Sub CloseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseToolStripMenuItem.Click Dim ad As Document = Me.ActiveMdiChild If Not ad Is Nothing Then ad.Close() End If End Sub Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click Me.Close() End Sub ’************************************ ’These event procedures deal with arranging child windows. Private Sub TileHorizontallyToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TileHorizontallyToolStripMenuItem.Click Me.LayoutMdi(MdiLayout.TileHorizontal) End Sub Private Sub TileVerticallyTileToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TileVerticallyTileToolStripMenuItem.Click Me.LayoutMdi(MdiLayout.TileVertical) End Sub Private Sub CascadeToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CascadeToolStripMenuItem.Click Me.LayoutMdi(MdiLayout.Cascade) End Sub ’***************************************** ’ These event procedures are for cut, copy, and paste. Private Sub CutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CutToolStripMenuItem.Click Dim ad As Document = Me.ActiveMdiChild If Not ad Is Nothing Then If ad.RichTextBox1.SelectionLength > 0 Then Clipboard.SetDataObject(ad.RichTextBox1.SelectedText) ad.RichTextBox1.SelectedText = "" End If End If End Sub Private Sub CopyToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CopyToolStripMenuItem.Click Dim ad As Document = Me.ActiveMdiChild If Not ad Is Nothing Then If ad.RichTextBox1.SelectionLength > 0 Then Clipboard.SetDataObject(ad.RichTextBox1.SelectedText) End If End If End Sub Private Sub PasteToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PasteToolStripMenuItem.Click Dim ad As Document = Me.ActiveMdiChild If Not ad Is Nothing Then Dim data As IDataObject = Clipboard.GetDataObject() If (data.GetDataPresent(DataFormats.Text)) Then ad.RichTextBox1.SelectedText = data.GetData(DataFormats.Text).ToString() End If End If End Sub ’************************************ ’ This sub is called to save a document. Private Sub SaveDocument(ByVal doc As Document, ByVal FileName As String) Try Dim sw As New StreamWriter(FileName) sw.Write(doc.RichTextBox1.Text) sw.Close() doc.isNamed = True doc.isDirty = False Catch ex As Exception MsgBox("There was an error saving the file.") End Try End Sub End Class
Listing 2 Code in the text editor’s child form.
Public Class Document ’ True if the document has a name other than the default one. Public isNamed As Boolean = False ’ True if the document content has changed since opening/saving. Public isDirty As Boolean = False Private Sub RichTextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RichTextBox1.TextChanged ’ Mark the document as dirty. isDirty = True End Sub End Class
Figure 1 shows the application in action.
Figure 1 The text editor in action.
If you want to take this application further, you will probably want to add a few more basics:
- Define the standard shortcut keys, such as Ctrl+C for Edit > Copy and Ctrl+N for File > New.
- Add a File > Save As command.
- Add code to prevent the accidental closing of unsaved documents.
- Permit the user to specify the font used for document display.