Site logo
Site logo
Programmieren aus Leidenschaft
Programmieren aus Leidenschaft

MDI Formulare (Teil 1)


Der Begriff MDI (Multiple Document Interface) mag für manch einen neu sein, doch hat sicherlich jeder schon mal mit solchen Programmen gearbeitet. MDI-Programme erlauben das gleichzeitige Bearbeiten von mehreren Dokumenten. Bekanntestes Beispiel für eine solche Anwendung: Microsoft Word.
Es ist nicht überraschend aber natürlich kann man in Word mehrere Textdateien gleichzeitig laden und bearbeiten. Und auch wenn man kein Textdokument geöffnet hat bleibt die für Word typische Menu- und Symbolleiste bestehen. Word ist eine MDI-Anwendung.
Ein Gegenbeispiel ist Windows Wordpad. Mit diesem Texteditor kann jeweils nur eine Datei bearbeitet weden. Benötigt man aber mehr als ein aktives Dokument so muß man eine weitere Instanz des Wordpads starten.
Auch in C# ist es ein Leichtes, eine MDI Anwendung zu erstellen. Als erstes braucht man hierfür einen Container in dem alle Unterformulare eingebettet werden. Erstellen wir aber zuerst wieder unsere schon bekannte "main"-Methode.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace Baukasten
{
   class OhneBaukasten
   {
      [STAThread]
      public static void Main()
      {
         ElternFormular meinFormular = new ElternFormular();
         Application.EnableVisualStyles();
         Application.Run(meinFormular);
      }
   }
}
Das hier auszuführende Programm ist das "Elternformular". Diese von System.Windows.Form abgeleitete Klasse könnte so aussehen:
using System;
using System.Windows.Forms;

namespace Baukasten
{
   class ElternFormular : Form
   {
      public ElternFormular ()
      {
         this.Text = "Guten Morgen";
         this.Size = new System.Drawing.Size(550, 300);
         this.IsMdiContainer = true;
       }
   }
}
Allein die Eigenschaft "IsMdiContainer" macht aus unserem Standartformular eine MDI-Container. Oder auch MDI-Elternformular genannt. Man sieht das recht eindeutig, da sich die Farbe dieses Formulars in ein dunkles grau ändert. In diesem grauen Bereich werden später unsere MDI-Kindformulare eingebettet. Zwar lassen sich im diesem dunkelgrauen Bereich auch Steuerelemente unterbringen, allerdings würde ich von allen - außer vielleicht einem Hintergrundbild - dringen abraten, da diese Steuerelemente später von unseren Kindformularen überdeckt werden. Viel mehr Sinn mach es hingegen, ein Menu einzubinden. Die grundlegende Vorgehensweise kennen wir noch aus dem letzten Kapitel. Ebenfalls in den Konstruktor schreiben wir dafür folgenden Programmcode:
MenuStrip meinMenu = new MenuStrip();

ToolStripMenuItem ersteMenuGruppe = new ToolStripMenuItem();
ersteMenuGruppe.Text = "Menue 1";
meinMenu.Items.Add(ersteMenuGruppe);

ToolStripMenuItem unterpunk1 = new ToolStripMenuItem();
unterpunk1.Text = "Unterpunkt 1 - Kind erzeugen";
unterpunk1.Click += new EventHandler(unterpunkt1_Click);

ersteMenuGruppe.DropDownItems.Add(unterpunk1);
this.Controls.Add(meinMenu);
Nicht vergessen dürfen wir natürlich den EventHandler der beim Klicken auf "Unterpunkt 1" ausgelöst wird.
void unterpunkt1_Click(object sender, EventArgs e)
{

}
Um ein Kindformular zu erzeugen brauchen wir natürlich erst einmal eine Klasse die unser Formular abbildet.
using System;
using System.Windows.Forms;

namespace Baukasten
{
   class KindFormular : Form
   {
      public KindFormular ()
      {
            this.Text = "Ich bin ein Kindformular";

            MenuStrip meinMenu = new MenuStrip();

            ToolStripMenuItem ersteMenuGruppe = new ToolStripMenuItem();
            ersteMenuGruppe.Text = "Datei";
            meinMenu.Items.Add(ersteMenuGruppe);

            ToolStripMenuItem unterpunk1 = new ToolStripMenuItem();
            unterpunk1.Text = "Speichern";

            ersteMenuGruppe.DropDownItems.Add(unterpunk1);
            this.Controls.Add(meinMenu);
      }
   }
}
Wie zu erkennen ist, hat auch unser Kindformular ein eignes Menu. Das ist nicht zwingend nötig, aber wie wir in Teil zwei dieses Kapitels sehen werden, ist es möglich das Menu des Kindformulars mit dem des Elternformulars zu verbinden. Aber erzeugen wir zunächst Instanzen unseres Kindformulars indem wir auf den "Unterpunkt1" im Menu des Elternformulars klicken.
void unterpunkt1_Click(object sender, EventArgs e)
{
   Kind meinKind = new Kind();
   meinKind.Show();
}
Wenn wir unser Programm jetzt testen, werden wir schnell merken, dass ein Klick auf "Unterpunk1" ein neues Formular erzeugt. Mehrere Klicks auch mehrere Formulare. Eine richtige Eltern-Kind Beziehung gibt es aber nicht. Denn obwohl wird unserem Elternformular die Eigenschaft "IsMdiContainer" zugewiesen haben, können wir unser Kindformular immer noch außerhalb des Elternformulares bewegen. Auch wenn wir unser Kindformular maximieren wird es nicht im Elternobjekt eingebettet, sondern füllt den kompletten Bildschirm aus. Es fehlt noch eine wichtige Programmzeile.
void unterpunkt1_Click(object sender, EventArgs e)
{
   Kind meinKind = new Kind();
   meinKind.MdiParent = this;
   meinKind.Show();
}
Erst die Eigenschaft MdiParent legt fest, ob das neue Formular wirklich ein Elternformular hat und welches das ist. Da wir das Kindformular im Elternformular erzeugen, ist "this" der einfachste Weg eine Eltern-Kind-Beziehung zu definieren. Ein erneuter Test unseres Programmes liefert jetzt ganz andere Ergebnisse. Maximieren wir unser Kindformular, wird der Text der Titelleiste, der Titelleiste des Elternformulars hinzugefügt. Genauso wie man es beispielsweise von Word kennt. Leider haben wir jetzt aber zwei Menus. Wie man diese Menus zusammenfügt lernen wir im nächsten Abschnitt.