Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Über den Autor
Vorwort zur 4. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Klassendesign und Vererbung
4 Weitere .NET-Datentypen
5 Weitere Möglichkeiten von C#
6 Projektmanagement und Visual Studio 2008
7 Fehlerbehandlung und Debugging
8 LINQ
9 Multithreading und asynchrone Methodenaufrufe
10 Arbeiten mit Dateien und Streams
11 Serialisierung
12 Einige wichtige .NET-Klassen
13 Grundlagen zum Erstellen einer Windows-Anwendung
14 Die wichtigsten Steuerelemente
15 Tastatur- und Mausereignisse
16 MDI-Anwendungen
17 Grafische Programmierung mit GDI+
18 Das Drucken (Printing)
19 Steuerelemente entwickeln
20 Programmiertechniken
21 WPF – die Grundlagen
22 Die Layoutcontainer
23 Die WPF-Controls
24 Konzepte von WPF
25 ADO.NET – die Verbindung zu einer Datenbank herstellen
26 Die Datenbankabfrage
27 Der SqlDataAdapter
28 Daten im lokalen Speicher – das DataSet
29 Eine Datenbank aktualisieren
30 Stark typisierte DataSets
31 Weitergabe von Anwendungen
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual C# 2008 von Andreas Kuehnel
Das umfassende Handbuch
Buch: Visual C# 2008

Visual C# 2008
geb., mit DVD
1.366 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1172-7
Pfeil 14 Die wichtigsten Steuerelemente
Pfeil 14.1 Gemeinsame Eigenschaften, Methoden und Ereignisse
Pfeil 14.1.1 Größe und Position
Pfeil 14.1.2 Die Sichtbarkeit und der Aktivierungszustand
Pfeil 14.1.3 Die Eigenschaft »Text«
Pfeil 14.1.4 Die Farbeigenschaften
Pfeil 14.1.5 Grafische Darstellung
Pfeil 14.1.6 Die »Modifiers«-Eigenschaft
Pfeil 14.1.7 Die Eigenschaft »Tag«
Pfeil 14.1.8 Die Größe von Steuerelementen dynamisch der Formgröße anpassen
Pfeil 14.1.9 Die »Dock«-Eigenschaft
Pfeil 14.1.10 Steuerelemente fokussieren
Pfeil 14.1.11 Maus- und Tastaturereignisse
Pfeil 14.2 Schaltflächen der Klasse »Button«
Pfeil 14.2.1 Die Rahmendarstellung einer Schaltfläche
Pfeil 14.2.2 Die Eigenschaft »FlatAppearance«
Pfeil 14.2.3 Beschriftung und Grafiken
Pfeil 14.3 Auswahlkästchen mit der Klasse »CheckBox«
Pfeil 14.3.1 Eigenschaften eines Kontrollkästchens
Pfeil 14.3.2 Checkboxen mit drei Aktivierungszuständen
Pfeil 14.4 Die Klasse »RadioButton« (Optionsschaltflächen)
Pfeil 14.4.1 Die Gruppierung der Optionsschaltflächen
Pfeil 14.4.2 Die Eigenschaften von Optionsschaltflächen
Pfeil 14.4.3 Den Zustandswechsel programmieren
Pfeil 14.5 Die »GroupBox« als übergeordneter Container
Pfeil 14.6 Texteingabefelder mit der Klasse »TextBox«
Pfeil 14.6.1 Einzeilige Eingabefelder
Pfeil 14.6.2 Mehrzeilige Eingabefelder
Pfeil 14.7 Beschriftungen mit dem Steuerelement »Label«
Pfeil 14.8 Die Anzeige eines Quickinfo-Texts
Pfeil 14.8.1 Methoden des »ToolTip«-Steuerelements
Pfeil 14.8.2 Aktivierungsdauer des »QuickInfo«-Steuerelements
Pfeil 14.8.3 Weitere Eigenschaften
Pfeil 14.9 Das »ListBox«-Steuerelement
Pfeil 14.9.1 Die Auflistung »ListBox.ObjectCollection«
Pfeil 14.9.2 Eigenschaften zur Darstellung einer Listbox
Pfeil 14.9.3 Einfach- und Mehrfachauswahl der Listenelemente
Pfeil 14.9.4 Programmgesteuerter Zugriff auf Listboxen mit Einfachauswahl
Pfeil 14.9.5 Benutzerdefiniertes Sortieren der Listenelemente
Pfeil 14.9.6 Füllen einer Listbox mit »DataSource«
Pfeil 14.10 Das Steuerelement »CheckedListBox«
Pfeil 14.11 Die »ComboBox« (Kombinationslistenfeld)
Pfeil 14.11.1 Ereignisse eines Kombinationslistenfeldes
Pfeil 14.11.2 Autovervollständigung in einer »ComboBox«
Pfeil 14.12 Standarddialoge
Pfeil 14.12.1 Die Klasse »OpenFileDialog«
Pfeil 14.12.2 Die Klasse »SaveFileDialog«
Pfeil 14.12.3 Der Dialog »FolderBrowserDialog«
Pfeil 14.12.4 Die Klasse »ColorDialog«
Pfeil 14.12.5 Die Klasse »FontDialog«
Pfeil 14.13 Menü-, Symbol- und Statusleiste sowie Kontextmenüs
Pfeil 14.13.1 Das Steuerelement »ToolStripContainer«
Pfeil 14.13.2 Bereitstellen eines Menüs
Pfeil 14.13.3 Kontextmenüs
Pfeil 14.13.4 Die Symbolleiste
Pfeil 14.13.5 Die Statusleiste
Pfeil 14.13.6 Eine Statusleiste bereitstellen
Pfeil 14.14 Bildlaufleisten mit »HScrollBar« und »VScrollBar«
Pfeil 14.15 Das »ProgressBar«-Steuerelement
Pfeil 14.16 Das »Timer«-Steuerelement
Pfeil 14.17 Das »Panel«-Steuerelement
Pfeil 14.18 Registerkarten mit »TabControl«
Pfeil 14.18.1 Die Klasse »TabControl«
Pfeil 14.19 Das »TreeView«-Steuerelement
Pfeil 14.19.1 Knotenpunkte im »TreeView« definieren
Pfeil 14.19.2 Eigenschaften des »TreeView«-Steuerelements
Pfeil 14.19.3 Die Ereignisse des »TreeView«-Steuerelements
Pfeil 14.19.4 Weitere Eigenschaften und Methoden des »TreeView«-Objekts
Pfeil 14.19.5 Eigenschaften und Methoden des »TreeNode«-Objekts
Pfeil 14.20 Die beiden »Splitter«-Steuerelemente
Pfeil 14.20.1 Das Steuerelement »Splitter«
Pfeil 14.20.2 Das Steuerelement »SplitContainer«
Pfeil 14.21 Das »ListView«-Steuerelement
Pfeil 14.21.1 Die Klassen des »ListView«-Steuerelements
Pfeil 14.21.2 Die Eigenschaften der »ListView«
Pfeil 14.21.3 Listenelemente vom Typ »ListViewItem«
Pfeil 14.21.4 Das Element »ListViewSubItem«
Pfeil 14.21.5 Der Typ »ColumnHeader«
Pfeil 14.21.6 Listenelemente Gruppen zuordnen
Pfeil 14.21.7 Sortierung der Spalten
Pfeil 14.21.8 Listenelemente ändern
Pfeil 14.21.9 Beispielanwendung


Galileo Computing - Zum Seitenanfang

14.12 Standarddialoge Zur nächsten ÜberschriftZur vorigen Überschrift

Bei Standarddialogen handelt es sich um Dialoge (Forms), die wir in nahezu jeder Windows-Anwendung vorfinden. Insgesamt fünf werden uns in der Toolbox als Steuerelemente angeboten, die – weil sie nicht direkt mit dem Benutzer interagieren – im Komponentenfach unterhalb des Windows Forms-Designers abgelegt werden:

  • ColorDialog
  • OpenFileDialog
  • FolderBrowserDialog
  • SaveFileDialog
  • FontDialog

Bis auf OpenFileDialog und SaveFileDialog sind alle direkt von der abstrakten Basisklasse CommonDialog abgeleitet. Die beiden angeführten Klassen haben in der abstrakten Klasse FileDialog noch eine weitere Basisklasse.

Die wichtigste Methode aller Standarddialoge ist ShowDialog. Sie dient zum Öffnen eines Dialogfensters, z. B.:

openFileDialog.ShowDialog();

Diese Methode liefert einen Rückgabewert vom Typ DialogResult.


Galileo Computing - Zum Seitenanfang

14.12.1 Die Klasse »OpenFileDialog« Zur nächsten ÜberschriftZur vorigen Überschrift

OpenFileDialog repräsentiert das Dialogfenster, in dem der Anwender zur Laufzeit die Datei auswählen kann, die er öffnen möchte. Die Klasse hat nur einen parameterlosen Konstruktor.

OpenFileDialog dlgFileOpen = new OpenFileDialog(); 
dlgFileOpen.ShowDialog();

Die beiden Anweisungen bewirken das Öffnen des Dialogfensters aus Abbildung 14.19. Es unterstützt die Navigation zu der Datei, die geöffnet werden soll. Sollten Sie aber glauben, dass nach dem Klicken auf die Schaltfläche die ausgewählte Datei auch tatsächlich geöffnet wird, werden Sie enttäuscht sein: Geöffnet wird mit diesem Dialog tatsächlich keine Datei; sie wird nur ausgewählt.

Abbildung 14.19 Der Standarddialog »OpenFileDialog«

Sowohl das Layout als auch das Verhalten eines OpenFileDialog-Fensters kann in einem bestimmten Rahmen an spezifische Anforderungen angepasst werden. Die Möglichkeiten der Einflussnahme wollen wir uns nun etwas genauer ansehen.

Die Beschriftung der Titelleiste

Standardmäßig wird in der Titelleiste des Dialogs die Beschriftung Öffnen angezeigt. Sie können den Titel mit der Eigenschaft Title beliebig festlegen.

OpenFileDialog dlgFileOpen = new OpenFileDialog(); 
dlgFileOpen.Title = "Öffnen eines Projektordners";

Festlegen eines Standardverzeichnisses

Wird der Dialog zum Öffnen einer Datei zum ersten Mal dargestellt, wird der Inhalt des Ordners angezeigt, in dem sich die ausführbare Datei befindet. Beim nächsten Öffnen ist es immer das Verzeichnis, aus dem heraus zuvor eine Datei ausgewählt worden ist. Das Verhalten kann beeinflusst werden, indem man die Eigenschaft InitialDirectory auf ein bestimmtes Verzeichnis festlegt oder eine entsprechende Anweisung codiert, bevor der Dialog geöffnet wird:

dlgFileOpen.InitialDirectory = @"C:\MyProjects";

Wenn Sie keinen Wert festlegen, enthält die Eigenschaft einen Leerstring.

Möglicherweise benötigen Sie aber eine Referenz zu einem systemspezifischen Verzeichnis. Um die notwendigen Informationen über die Umgebung der aktuellen Maschine zu erhalten, können Sie auf die Dienste der Klasse Environment der .NET-Klassenbibliothek zurückgreifen.

Die Klasse Environment ist im Namespace System definiert und veröffentlicht Eigenschaften und Methoden, die zum Abrufen von maschinenspezifischen Informationen nützlich sind – beispielsweise die statische Methode GetFolderPath, die den Pfad eines bestimmten Systemordners abruft. Diese erwartet als Argument einen Wert der Enumeration Environment.SpecialFolder. Die folgende Tabelle beschreibt nur einen Auszug der Enumeration. Um einen vollständigen Überblick über alle Mitglieder zu erhalten, sollten Sie in der .NET-Dokumentation nachsehen.


Tabelle 14.10 Konstanten der Enumeration »Environment.SpecialFolder«

Member Rückgabewert (Standardinstallationsvorgabe)

CommonProgramFiles

C:\Programme\Gemeinsame Dateien

History

C:\Dokumente und Einstellungen\<User>\Lokale Einstellungen\Verlauf

Personal

C:\Dokumente und Einstellungen\<User>\Eigene Dateien

ProgramFiles

C:\Programme

Programs

C:\Dokumente und Einstellungen\ <User>\ Startmenü\ Programme

Recent

C:\Dokumente und Einstellungen\<User>\Recent

StartMenu

C:\Dokumente und Einstellungen\<User>\Startmenü

Startup

C:\Dokumente und Einstellungen\<User>\Startmenü \Programme\Autostart

System

C:\WINNT\System32


Falls Sie das zu öffnende Standardverzeichnis auf den Ordner

C:\Dokumente und Einstellungen\<User>\Eigene Dateien

festlegen möchten, muss die Anweisung dazu wie folgt lauten:

dlgFileOpen.InitialDirectory = 
   Environment.GetFolderPath(Environment.SpecialFolder.Personal)

Einen Dateifilter setzen

Die Eigenschaft Filter des OpenFileDialog-Steuerelements legt die Dateitypen fest, die dem Anwender aus dem angezeigten Ordner zum Öffnen angeboten werden, z. B.:

dlgFileOpen.Filter = "Textdateien (*.txt)|*.txt";

Welche Dateitypen gefiltert werden, kann der Anwender durch eine entsprechende Auswahl in einem Kombinationslistenfeld unterhalb des Anzeigebereichs bestimmen.

Die durch die Eigenschaft Filter beschriebene Zeichenfolge unterliegt einem strengen Muster. Die Anweisung oben definiert einen Dateifilter, durch den im Auswahlbereich des Dialogs nur Textdateien mit der Dateierweiterung .txt angeboten werden. Die Zeichenfolge zur Festlegung eines Filters setzt sich immer aus zwei Teilen zusammen, die durch einen senkrechten Strich voneinander getrennt werden. Die Teilzeichenfolge links vom Strich wird dem Benutzer im Kombinationslistenfeld Dateityp angezeigt, und die rechts vom Strich stehende Teilzeichenfolge ist die Anweisung an den Dialog, nach welchen Kriterien die Dateien gefiltert werden sollen. Das »*«-Zeichen dient als Platzhalter.

Soll das Kombinationslistenfeld mehrere Auswahloptionen anbieten, ergänzen Sie die Zeichenfolge der Filter-Eigenschaft nach dem bekannten Muster um die gewünschten Dateien. Zur Abgrenzung untereinander verwenden Sie ebenfalls einen senkrechten Strich.

Im folgenden Beispiel wird das Kombinationslistenfeld mit zwei Einträgen gefüllt: Der erste ist die Filterung nach Textdateien, und die zweite Auswahloption zeigt sämtliche Dateien des geöffneten Ordners an.

dlgFileOpen.Filter = "Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*";

Wird zur Laufzeit der Anwendung die erste Auswahl getroffen, werden die TXT-Dateien herausgefiltert; entscheidet sich der Anwender für die zweite, werden alle Dateien, unabhängig von der Dateierweiterung, angezeigt.

Die im Kombinationslistenfeld angebotene Liste kann durchaus sehr lang werden, wenn Sie den Anwender mit vielen Filteroptionen verwöhnen wollen, schreiben Sie beispielsweise:

dlgFileOpen.Filter = 
    "Textdateien (*.txt)|*.txt| HTML-Dateien|*.htm;*.html|" 
    + "Bitmap-Dateien (*.tif)|*.tif|" 
    + "Ausführbare Dateien (*.exe)|*.exe|" 
    + "Word-Dokumente(*.doc)|*.doc|" 
    + "Alle Dateien (*.*)|*.*)";

Manchmal möchte man auch mehrere Dateitypen gleichzeitig anzeigen lassen. Das ist beispielsweise der Fall, wenn Sie nach mehreren Bildformaten filtern wollen. Listen Sie dazu in der rechten Teilzeichenfolge alle gewünschten Dateiformate auf. Diese müssen durch ein Semikolon voneinander getrennt werden:

dlgFileOpen.Filter = "Alle Bilddateien|*.tif;*.jpeg;*.gif";

Den anwendungsspezifischen Standardfilter festlegen

Normalerweise wird nach dem Öffnen des Dialogs der zuerst aufgeführte Filter im Kombinationslistenfeld angezeigt. Mit der Eigenschaft FilterIndex kann aber auch ein beliebiger Filter aus der Liste gewählt werden:

dlgFileOpen.FilterIndex = 1;

Entgegen den sonst üblichen Gepflogenheiten beginnt die Indizierung der Filter nicht mit dem Index 0, sondern mit dem Index 1. Soll nach dem Öffnen des Dialogs beispielsweise nach den im angezeigten Verzeichnis befindlichen Word-Dokumenten gefiltert werden (siehe Codefragment oben), muss der Eigenschaft FilterIndex die Zahl 5 übergeben werden.

Die ausgewählte Datei

Das Ziel des Dialoges ist es, eine Datei auszuwählen und diese Auswahl im weiteren Programmcode zum tatsächlichen Öffnen der Datei zu verwenden. Die Eigenschaft, die uns den Dateinamen einschließlich der gesamten Pfadangabe liefert, ist FileName. Den Rückgabewert können wir als Übergabeargument bei der Instanziierung einer Klasse aus dem Namespace System.IO mit einem Konstruktor benutzen, der einen path-Parameter entgegennimmt, z. B.:

OpenFileDialog dlgFileOpen = new OpenFileDialog(); 
if(dlgFileOpen.ShowDialog() == DialogResult.OK) 
  StreamReader sr = new StreamReader(ofd.FileName); 
...

Mehrfachauswahl von Dateien

Möchten Sie eine Mehrfachauswahl von Dateien zulassen, müssen Sie die Eigenschaft MultiSelect des Dialogs auf true setzen. Das Verhalten bei der Dateiauswahl entspricht dann dem eines Listenfeldes mit erweiterter Mehrfachauswahl.

Bei einer einfachen Auswahlmöglichkeit kann man den Pfad zu der zu öffnenden Datei über die Eigenschaft FileName abfragen. Bei der Mehrfachauswahl steht mit FileNames eine ähnlich lautende Eigenschaft zur Verfügung, deren Rückgabewert ein Array vom Typ string ist:

public string[] FileNames {get;}

Im Gegensatz zu FileName ist diese Eigenschaft schreibgeschützt.

Ereignisse von »OpenFileDialog«

Nur zwei spezifische Ereignisse zeichnen das Dialogfeld aus. Zum einen können Sie in Verbindung mit dem Klicken auf die Schaltfläche OK einen Ereignishandler mit dem Ereignis FileOK verknüpfen. Anstatt die Rückgabe des Aufrufs der Methode ShowDialog auszuwerten, können Sie somit auch im Ereignishandler auf die Dateiauswahl im Dialog reagieren. Unter bestimmten Umständen ist das Auswerten des Ereignisses FileOk flexibler, denn der Ereignishandler empfängt ein Argument vom Typ CancelEventArgs, das es uns erlaubt, über die Eigenschaft Cancel das Schließen des Dialogs zu verhindern. Dadurch wird es dem Anwender möglich, mehrere Dateien einzeln hintereinander auszuwählen, ohne dass der Dialog wiederholt geöffnet werden muss.

Das Ereignis HelpRequest setzt voraus, dass die Eigenschaft ShowHelp=true gesetzt ist und im Dialog eine Hilfe-Schaltfläche angezeigt wird. Ausgelöst wird dieses Ereignis durch Anklicken dieser Schaltfläche.

Das Beispiel »Texteditor«

Im folgenden Beispiel wollen wir einen einfachen Texteditor entwickeln und für die allgemeinen Operationen zum Öffnen und Speichern Standarddialoge benutzen. Zunächst soll nur das Öffnen von Dateien implementiert werden. Später wird das Beispiel auch um die Speicherung der Dokumentinformationen ergänzt.

Die Form des Texteditors enthält eine Textbox, die auch dann den gesamten Clientbereich der Form ausfüllt, wenn die Form zur Laufzeit vergrößert oder verkleinert wird. Am einfachsten ist das zu realisieren, wenn die Eigenschaft Dock der Textbox auf DockStyle.Fill eingestellt wird. Das Formular enthält ein Menü mit dem Hauptmenüpunkt Datei und den Menüunterelementen Öffnen, Neu, Speichern, Speichern unter und Beenden.

Mit dem Erstellen eines Menüs werden wir uns später beschäftigen. Im Moment ist es für Sie nur wichtig zu wissen, dass ein Menüelement das Ereignis Click bereitstellt, das ausgelöst wird, sobald der Anwender einen Menüpunkt auswählt.

Abbildung 14.20 Formular des Beispiels »TexteditorVers1«

// --------------------------------------------------------------
// Beispiel: ...\Kapitel 14\TexteditorVers1
// ------------------------------------------------------------------
// Ereignishandler des Click-Ereignisses des Menüs 'Öffnen' 
private void mnuOeffnen_Click(object sender, EventArgs e) { 
  // Standarddialog zum Öffnen anzeigen 
  OpenFileDialog ofd = new OpenFileDialog(); 
  ofd.Filter = "Textdateien (*.txt)|*.txt|" 
                   + "Alle Dateien (*.*)|*.*"; 
  ofd.Title = "Öffnen einer Textdatei"; 
  if (ofd.ShowDialog() == DialogResult.OK) { 
    // falls ein Fehler auftreten sollte, muss dieser behandelt werden 
    try { 
      StreamReader sr = new StreamReader(ofd.FileName); 
      txtDatei.Text = sr.ReadToEnd(); 
      sr.Close(); 
    } 
    catch(Exception ex) { 
      MessageBox.Show(ex.Message, "Texteditor"); 
    } 
  } 
}

// Ereignishandler des Click-Ereignisses des Menüs 'Beenden' 
private void mnuBeenden_Click(object sender, EventArgs e) { 
  string strMeldung = "Wollen Sie die Anwendung beenden?"; 
  DialogResult result = MessageBox.Show(strMeldung, 
                            Application.ProductName, 
                            MessageBoxButtons.OKCancel, 
                            MessageBoxIcon.Question, 
                            MessageBoxDefaultButton.Button2); 
  if(result == DialogResult.OK) 
    Application.Exit(); 
}

// Ereignishandler des Click-Ereignisses des Menüs 'Neu' 
private void mnuNeu_Click(object sender, EventArgs e) { 
  txtDatei.Text = ""; 
}

Im Zusammenhang mit dem Thema dieses Abschnitts ist der wichtigste Codeabschnitt der Dialog zum Öffnen einer Textdatei:

OpenFileDialog ofd = new OpenFileDialog(); 
... 
if (ofd.ShowDialog() == DialogResult.OK) { ... }

Wie alle modalen Dialogfenster liefert der Aufruf der Methode ShowDialog einen Rückgabewert vom Typ DialogResult. Wir müssen nur noch feststellen, auf welche Schaltfläche der Anwender im Dialog geklickt hat, denn nur mit der Bestätigung durch OK soll die markierte Datei auch geöffnet und im Textfenster angezeigt werden.

Eine Textdatei kann mit mehreren Klassen des Namespace System.IO realisiert werden. Im Beispiel wird die Klasse StreamReader eingesetzt und dem Konstruktor die Eigenschaft FileName des Dialogs zugewiesen. Die Methode ReadToEnd liest von der aktuellen Position des Dateizeigers bis zum Ende der Datei ein und berücksichtigt dabei auch Zeilenumbrüche innerhalb des Textes. Der eingelesene Dateiinhalt wird in der Textbox angezeigt, und anschließend wird das StreamReader-Objekt ordnungsgemäß geschlossen.

StreamReader sr = new StreamReader(ofd.FileName); 
txtDatei.Text = sr.ReadToEnd(); 
sr.Close();

Da insbesondere Dateioperationen schnell einen Fehler verursachen können, wird das Öffnen und Einlesen in einen try-Anweisungsblock eingeschlossen. Sollte eine Ausnahme auftreten, wird die Fehlermeldung in einem Meldungsfenster angezeigt.


Galileo Computing - Zum Seitenanfang

14.12.2 Die Klasse »SaveFileDialog« Zur nächsten ÜberschriftZur vorigen Überschrift

Die Klasse SaveFileDialog stellt ein Dialogfenster dar, das den Anwender zum Speichern einer Datei auffordert. Da die beiden Klassen SaveFileDialog und OpenFileDialog in FileDialog eine gemeinsame Basisklasse haben, ähneln sich beide Dialoge nicht nur optisch, sondern weisen auch viele gemeinsame Eigenschaften auf, beispielsweise Title, InitialDirectory und Filter. Verschaffen wir uns daher einen Überblick über die Eigenschaften, durch die sich die beiden Klassen unterscheiden.


Tabelle 14.11 Spezifische Eigenschaften der Klasse »SaveFileDialog«

Eigenschaft Beschreibung

AddExtension

Ruft einen Wert ab oder legt einen Wert fest, der angibt, ob einem Dateinamen im Dialogfeld automatisch eine Erweiterung hinzugefügt wird, wenn der Benutzer keine Erweiterung angibt.

DefaultExt

Legt die Standarddateinamenerweiterung fest oder ruft diese ab.

CreatePrompt

Wenn auf true gesetzt, wird ein Meldungsfenster beim Speichern unter einem noch nicht vorhandenen Dateinamen angezeigt. Der Anwender muss den Speichervorgang bestätigen.

OverwritePrompt

Bei der Standardeinstellung true wird ein Meldungsfenster angezeigt, wenn unter einem Dateinamen gespeichert werden soll, der im aktuellen Ordner bereits existiert. Der Anwender muss das Überschreiben der vorhandenen Datei bestätigen.


Viele Anwendungen ermöglichen es einem Benutzer, auch ohne die Angabe einer Dateierweiterung eine Datei zu speichern. Eine passende Dateierweiterung wird dann automatisch angehängt. MS Word erweitert den Dateinamen beispielsweise um die Erweiterung .DOC, der Texteditor Notepad um .TXT. Wollen Sie diese Unterstützung auch in Ihrer eigenen Anwendung realisieren, setzt das zunächst voraus, dass die Eigenschaft AddExtension=true gesetzt wird. Der Eigenschaft DefaultExt teilen Sie die gewünschte Standarddateinamenerweiterung mit.

Übergeben Sie der Eigenschaft DefaultExt nicht den Punkt, der Dateinamen und Dateierweiterung voneinander trennt. Der Punkt wird automatisch eingefügt. Wenn Sie eine anwendungsspezifische Dateierweiterung festgelegt haben und der Anwender die Dateierweiterung trotzdem angibt, erkennt der Dialog das und hängt keine zweite Erweiterung an.

saveFileDialog1.AddExtension = true; 
saveFileDialog1.DefaultExt = "csh";

Die beiden Eigenschaften CreatePrompt und OverwritePrompt informieren den Anwender mit einem Meldungsfenster. Ist CreatePrompt=true und gibt der Anwender einen Dateinamen an, der im aktuell geöffneten Verzeichnis des Dialogs noch nicht vorhanden ist, wird im Meldungsfenster um Bestätigung gebeten, ob die Datei neu erstellt werden soll.

Wenn Sie den Standardwert true der Eigenschaft OverwritePrompt übernehmen, wird ein Meldungsfenster angezeigt, mit dem der Anwender bestätigen kann, ob eine vorhandene Datei gleichen Namens überschrieben werden soll.

Der Speichern-Dialog am Beispiel von »TexteditorVers2«

Das Beispiel TexteditorVers1 aus Abschnitt 14.12.1 soll jetzt um eine Speicherfunktionalität erweitert werden. Der zusätzliche Code ist verhältnismäßig komplex, denn um den allgemein üblichen Anforderungen zu genügen, reicht es nicht aus, nur die Click-Ereignisse der beiden Menüelemente Speichern und Speichern unter... zu implementieren. Ein Dokument, das nach einem Speichervorgang eine Änderung erfahren hat, muss nämlich beispielsweise beim Schließen noch einmal automatisch oder auf Bestätigung hin gespeichert werden.

Eine der wichtigsten Informationen in unserem Beispielprogramm wird im Feld strFile vom Typ string vorgehalten. Dieses Feld enthält die Information, in welcher Datei der Inhalt der Textbox gespeichert worden ist. Ist das Feld leer oder null, wurde der Inhalt noch nicht gespeichert.

Wird der Inhalt der Textbox gespeichert, enthält strFile eine gültige Angabe. Zusätzlich benötigen wir aber auch noch die Information, ob sich der Textboxinhalt nach einer Speicherung noch einmal verändert hat. Das ist beispielsweise dann von Interesse, wenn das Formular geschlossen wird. Ist der aktuelle Inhalt bereits abgespeichert, kann das Fenster sofort geschlossen werden. Andernfalls muss der Anwender die Entscheidung treffen, ob er den letzten Stand speichern oder verwerfen will.

Der Mittelpunkt aller Speichervorgänge wird die benutzerdefinierte Methode SaveToFile sein, in der der Inhalt der Textbox einem Stream übergeben wird. Wir benutzen dazu ein Objekt vom Typ StreamWriter, an dessen Konstruktor wir den Inhalt des Feldes strFile übergeben – also die Information über den Speicherort. Über einen zweiten Parameter teilen wir mit, dass wir die vorhandene Datei überschreiben wollen. Mit der Write-Methode werden die Daten in die Datei geschrieben. Den Dateizugriff sichern wir mit einer Ausnahmebehandlung. Sollte kein Fehler auftreten, kann die Eigenschaft Modified der Textbox auf false gesetzt werden.

// Methode zum Speichern des Textboxinhalts 
private void SaveToFile() { 
  try { 
    StreamWriter sw = new StreamWriter(strFile, false); 
    sw.Write(txtDatei.Text); 
    sw.Close(); 
  } 
  catch(Exception e) { 
    MessageBox.Show(e.Message); 
    return; 
  } 
  txtDatei.Modified = false; 
}

Angestoßen wird das Speichern immer dann, wenn sich der Inhalt der Textbox geändert hat (dann gilt: Modified=true). Dabei gilt es, zwei Ausgangssituationen zu berücksichtigen:

  • Der Inhalt der Textbox ist während der Sitzung noch nicht gespeichert worden. Dann ist der Inhalt des Feldes strFile leer oder null.
  • Eine vorherige Speicherung hat das Feld strFile mit einem gültigen Wert belegt.

Die Prüfung, ob der Inhalt der Textbox bereits gespeichert worden ist, führt die Methode SaveDocument durch. Sie gibt auch den Anstoß zum Speichern.

private void SaveDocument() { 
  if(this.strFile != null && this.strFile.Length > 0) 
    saveFileDialog1.FileName = this.strFile;

  if (saveFileDialog1.ShowDialog() == DialogResult.OK) { 
    this.strFile = saveFileDialog1.FileName; 
    this.SaveToFile(); 
    this.SetFormTitle(); 
  } 
}

Die Methode prüft zuerst den Inhalt von strFile. Falls das Feld einen gültigen Wert aufweist, wird dieser der Eigenschaft FileName des SaveFileDialog-Objekts übergeben. Anschließend kann der Dialog geöffnet werden. Bevor wir die Datei endgültig speichern, müssen wir berücksichtigen, dass der Anwender unter Umständen einen anderen Dateinamen eingetragen hat. Deshalb wird mit

this.strFile = saveFileDialog1.FileName;

der aktuelle Inhalt der Eigenschaft FileName dem Feld strFile übergeben und erst danach die Methode SaveToFile aufgerufen.

Üblicherweise werden in Texteditoren die Dateinamen des aktuell bearbeiteten Dokuments in der Titelleiste angezeigt. Wir realisieren das mit der Methode SetFormTitle:

private void SetFormTitle() { 
  if (this.strFile == null || this.strFile.Length == 0) 
    this.Text = "Unbenannt - " + "Texteditor"; 
  else 
    this.Text = Path.GetFileName(this.strFile) + " - " 
                  + "Texteditor"; 
}

Wenden wir uns nun den Speichervorgängen zu und hier zuerst dem Menü Speichern. Der Anwender könnte zur Laufzeit diese Option wählen, obwohl der Inhalt der Textbox vorher noch nicht gespeichert worden ist. In diesem Fall enthält strFile keine gültige Pfadangabe, und der Dialog zum Speichern muss in jedem Fall geöffnet werden. Das haben wir in der Methode SaveDocument implementiert.

Hat der Anwender jedoch vorher gespeichert, ist der Pfad zu der Datei im Feld strFile eingetragen. Es ist dann nicht nötig, den Speichern-Dialog anzuzeigen, und das StreamWriter-Objekt kann in der Methode SaveToFile sofort aktiv werden.

// Ereignishandler des Click-Ereignisses des Menüs 'Speichern' 
private void mnuSpeichern_Click(object sender, EventArgs e) { 
  if(this.strFile == null || this.strFile.Length == 0) 
    this.SaveDocument(); 
  else 
    this.SaveToFile(); 
}

Noch einfacher ist der Code des Ereignishandlers, der dem Menüelement Speichern unter... zugeordnet ist. Entscheidet sich der Anwender für diese Option, möchte er die Datei unter einem anderen Namen speichern. Wir müssen den Aufruf nur an SaveDocument weiterleiten.

// Ereignishandler des Click-Ereignisses des Menüs 'Speichern unter...' 
private void mnuSpeichernUnter_Click(object sender, EventArgs e) { 
  this.SaveDocument(); 
}

Der Anwender könnte auch den Menüpunkt Neu wählen, wenn sich in der Textbox noch Informationen befinden, die noch nicht gespeichert worden sind. Deshalb muss im entsprechenden Ereignishandler zuerst die Eigenschaft Modified der Textbox untersucht werden. Ist der Inhalt true, wird der Anwender durch ein Meldungsfenster dazu aufgefordert, anzugeben, ob er den Inhalt seines Dokuments speichern oder doch lieber verwerfen möchte. Entscheidet er sich für das Speichern, bleibt wieder die Frage zu klären, ob der Inhalt zum ersten oder zum wiederholten Mal gespeichert wird. Abhängig davon wird entweder automatisch im Hintergrund gespeichert oder der Dialog zum Speichern geöffnet.

// Ereignishandler des Click-Ereignisses des Menüs 'Neu' 
private void mnuNeu_Click(object sender, EventArgs e) { 
  if (txtDatei.Modified == true) { 
    DialogResult dr = 
        MessageBox.Show("Wollen Sie den Inhalt des Dokuments " + 
           "speichern?", "Texteditor", 
           MessageBoxButtons.YesNo, 
           MessageBoxIcon.Question, 
           MessageBoxDefaultButton.Button2); 
    switch(dr) { 
 
      case DialogResult.Yes: 
        if(this.strFile == null || this.strFile.Length == 0) 
          this.SaveDocument(); 
        else { 
          this.SaveToFile(); 
          txtDatei.Modified = false; 
        } 
            break; 
         case DialogResult.No: 
            return; 
    } 
  } 
  txtDatei.Text = ""; 
  txtDatei.Modified = false; 
  strFile = null; 
  this.SetFormTitle(); 
}

Nun haben wir nahezu alle Menüelemente berücksichtigt. Trotzdem können wir das bisherige Ergebnis aber noch nicht als vollständig ansehen. Wir müssen auch bedenken, dass der Anwender das Programm beenden könnte, ohne vorher zu speichern. Der Texteditor unseres Beispiels kann

  • durch die Wahl des Menüs Beenden,
  • über das Systemmenü oder über die X-Schaltfläche in der Titelleiste

geschlossen werden. Die Programmlogik, die hinter beiden Aktionen ausgeführt werden muss, ist dieselbe. Deshalb können wir auch eine allgemeine Methode entwickeln, die von dem Ereignishandler des Menüs Beenden und dem FormClosing-Ereignis der Form aufgerufen wird.

private void SaveOnClosing() { 
  if(txtDatei.Modified == false) 
    return; 
  DialogResult dr = 
     MessageBox.Show("Wollen Sie den Inhalt des Dokuments " + 
                     "speichern?", "Texteditor", 
                     MessageBoxButtons.YesNo, 
                     MessageBoxIcon.Question, 
                     MessageBoxDefaultButton.Button2); 
  switch(dr) { 
    case DialogResult.Yes: 
      if(this.strFile == null || this.strFile.Length == 0) 
        this.SaveDocument(); 
      else { 
        this.SaveToFile(); 
        txtDatei.Modified = false; 
      } 
      break; 
    case DialogResult.No: 
      return; 
  } 
}

Vergleichen Sie diese Methode mit dem Ereignishandler des Menüelements Neu, werden Sie feststellen, dass wir den Code weiter vereinfachen können, weil die Kernpassage identisch mit SaveOnClosing ist. Das führt uns zum folgenden Ergebnis:

// überarbeiteter Ereignishandler des Click-Ereignisses des Menüs 'Neu' 
private void mnuNeu_Click(object sender, EventArgs e) { 
  // wenn das aktuelle Dokument nicht verändert worden ist 
  this.SaveOnClosing(); 
  txtDatei.Text = ""; 
  txtDatei.Modified = false; 
  strFile = null; 
  this.SetFormTitle(); 
}

Der Code des mit Closing verknüpften Ereignishandlers reduziert sich auf den einfachen Aufruf von SaveOnClosing:

private void Form1_FormClosing(object sender, CancelEventArgs e) { 
  this.SaveOnClosing(); 
}

Was noch fehlt, ist der Code für das Menüelement Beenden. Hier wird wieder SaveOnClosing aufgerufen, jedoch wird vorher ein Meldungsfenster eingeblendet, um das Schließen vom Anwender bestätigen zu lassen. Um denselben Methodenaufruf muss auch noch der Ereignishandler des Öffnen-Menüelements ergänzt werden.

private void mnuBeenden_Click(object sender, EventArgs e) { 
  string strMeldung = "Wollen Sie die Anwendung beenden?"; 
  DialogResult result = MessageBox.Show(strMeldung, 
       Application.ProductName, MessageBoxButtons.OKCancel, 
       MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);

  if(result == DialogResult.OK) { 
    this.SaveOnClosing(); 
    Application.Exit(); 
  } 
}

Den gesamten Code des Beispiels finden Sie auf der Buch-DVD unter

..\Kapitel 14\TexteditorVers2.


Galileo Computing - Zum Seitenanfang

14.12.3 Der Dialog »FolderBrowserDialog« Zur nächsten ÜberschriftZur vorigen Überschrift

Mit dem Steuerelement OpenFileDialog können Sie eine bestimmte Datei auswählen. Das Steuerelement bietet jedoch keine Möglichkeit, die Wahl auf einen Ordner zu beschränken. Dafür stellt das .NET Framework ein anderes Steuerelement zur Verfügung: FolderBrowserDialog. Etwas enttäuschend ist das Layout des Dialogs. Während uns in anderen Anwendungen ein Dialog angeboten wird, der dem Dialog zum Öffnen einer Datei ähnelt (unter anderem auch von Visual Studio), präsentiert sich die Oberfläche eines FolderBrowserDialog-Objekts nach dem Aufruf der Methode ShowDialog ziemlich spartanisch.

Abbildung 14.21 Das »FolderBrowserDialog«-Fenster

Es ist nur in einem sehr begrenzten Rahmen möglich, die Anzeige des Dialogs zu beeinflussen. Oberhalb des Anzeigebereichs können Sie einen Text ausgeben. Die entsprechende Zeichenfolge weisen Sie der Eigenschaft Description zu.

Standardmäßig kann ein Anwender aus allen lokalen oder sich im Netzwerk befindlichen Ordnern auswählen. Mit der Eigenschaft RootFolder kann ein anderer Ordner zum Stammordner des Dialogs gemacht werden.

Wenn Sie es dem Benutzer nicht erlauben wollen, einen neuen Ordner mit der Schaltfläche Neuer Ordner anzulegen, müssen Sie die Schaltfläche ausblenden. Dazu dient die Eigenschaft ShowNewFolderButton, der Sie dann false übergeben müssen. Die Pfadangabe des ausgewählten Ordners kann nach dem Schließen des Dialogs mit der Eigenschaft SelectedPath ausgewertet werden, die vom Typ string ist.


Galileo Computing - Zum Seitenanfang

14.12.4 Die Klasse »ColorDialog« Zur nächsten ÜberschriftZur vorigen Überschrift

Noch einfacher als OpenFileDialog und SaveFileDialog ist das Dialogfenster zu programmieren, das es dem Anwender ermöglicht, interaktiv Farben auszuwählen, beispielsweise um der Eigenschaft BackColor oder ForeColor zur Laufzeit eine neue Farbe zuzuweisen.

Zum Öffnen des Dialogs wird ebenfalls die Methode ShowDialog aufgerufen. Danach sieht das Standarddialogfeld zur Farbauswahl wie folgt aus (siehe Abbildung 14.22).

Abbildung 14.22 Das Standarddialogfeld »ColorDialog«

Ein Klick auf die Schaltfläche Farben definieren erweitert das Fenster und ermöglicht es dem Anwender, über die vordefinierten Farben hinaus nach seinen eigenen Vorstellungen Farbwerte festzulegen. Beabsichtigen Sie, dem Anwender von Anfang an das erweiterte Dialogfenster anzubieten, müssen Sie vor dem Öffnen des Dialogs die Eigenschaft FullOpen=true setzen.

Es bleibt die Frage zu klären, welche Eigenschaft des ColorDialog-Objekts ausgewertet werden muss, um zum Beispiel die Hintergrundfarbe des Formulars zu ändern: Es handelt sich um Color.

Im folgenden Codefragment wird die Hintergrundfarbe der Form gemäß der Auswahl im Dialog verändert. Dem Benutzer wird der erweiterte Dialog angezeigt. Wir werten allerdings nur die OK-Schaltfläche des Dialogs aus, da die Abbrechen-Schaltfläche bedeutungslos ist:

private void btnSetColor_Click(object sender, EventArgs e) { 
  colorDialog1.FullOpen = true; 
  if(colorDialog1.ShowDialog() == DialogResult.OK) 
    this.BackColor = colorDialog1.Color; 
}

Im Zustand FullOpen hat der Anwender die Möglichkeit, 16 benutzerdefinierte Farben festzulegen, die beim erneuten Öffnen des Dialogs weiterhin zur Auswahl bereitstehen. Allerdings wird der Dialog, den wir mit unserem Codefragment oben öffnen, dieses Verhalten nicht zeigen, denn die Wiedergabe bereits festgelegter benutzerdefinierter Farben ist kein Standardverhalten, sondern benötigt zusätzlichen Programmcode. Verantwortlich für das Speichern benutzerdefinierter Farben ist die Eigenschaft CustomColors.

Damit die vom Anwender ausgewählten Farben zur Laufzeit zur Verfügung stehen, müssen wir zuerst ein int-Array mit ausreichender Kapazität deklarieren:

int[] myColors = new int[16];

Bevor mit ShowDialog das Dialogfenster geöffnet wird, weisen wir den Inhalt dieses Arrays der Eigenschaft CustomColors zu:

colorDialog1.CustomColors = myColors;

Nach dem Schließen des Dialogs werden die Farben im Array gespeichert und stehen bei einem späteren erneuten Öffnen des Dialogs zur Verfügung:

myColors = colorDialog1.CustomColors;

Fassen wir zum Abschluss den Code in einem Click-Ereignishandler zusammen:

public partial class Form1 : Form { 
  private int[] myColors = new int[16]; 
  ...

  private void btnSetColor_Click(object sender, EventArgs e) { 
    fontDialog1.FullOpen = true; 
    if(colorDialog1.ShowDialog() == DialogResult.OK) 
      this.BackColor = colorDialog1.Color; 
    myColors = colorDialog1.CustomColors; 
  } 
}

Galileo Computing - Zum Seitenanfang

14.12.5 Die Klasse »FontDialog« topZur vorigen Überschrift

Der nächste Vertreter in der Runde der Standarddialoge ist FontDialog. Dieser Dialog ermöglicht die Auswahl einer Schriftart und des Schriftstils. Die Auswahl kann nach dem Bestätigen mit OK der Font-Eigenschaft zugewiesen werden.

Das Erscheinungsbild des Dialogs kann durch die vier Eigenschaften manipuliert werden, die in Tabelle 14.12 aufgeführt sind.


Tabelle 14.12 Eigenschaften zur Darstellung des Dialogs »FontDialog«

Eigenschaft Beschreibung

ShowApply

Wenn auf true gesetzt, hat der Dialog eine Übernehmen-Schaltfläche.

ShowColor

Wenn auf true gesetzt, wird im Dialogfeld die Farbauswahl angezeigt.

ShowEffects

Wenn auf false gestellt, können Unterstrichen oder Durchgestrichen nicht ausgewählt werden.

ShowHelp

Wenn auf true gesetzt, enthält der Dialog eine Hilfe-Schaltfläche.


Mit zwei Eigenschaften des FontDialog-Objekts kann die Schrift in einer Komponente beeinflusst werden: Color und Font. Die Farbe, die im FontDialog-Objekt eingestellt wird, ist die Schriftfarbe einer Komponente, die durch die Eigenschaft ForeColor beschrieben wird. Die Eigenschaft Font beschreibt die Schrift mit allen ihren spezifischen Darstellungen (fett, kursiv usw.).

Mit MinSize und MaxSize lässt sich festlegen, innerhalb welcher Spanne die Schriftgröße ausgewählt werden kann. MaxSize muss größer MinSize sein, und beide Werte müssen größer als 0 sein. Wenn Sie den Wert 0 eingeben, entspricht das der Standardeinstellung. Haben beide Eigenschaften denselben Wert, ist dieser als konstanter Wert der Schriftgröße anzusehen, die der Benutzer nicht ändern kann.

Eine weitere erwähnenswerte Eigenschaft ist FixedPitchOnly vom Typ Boolean. Hat die Eigenschaft den Wert true, werden im Dialog nur Schriftarten mit fester Zeichenbreite angeboten. Ein typisches Beispiel dafür ist der Schrifttyp Courier.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2008
Visual C# 2008
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Visual C# 2012






 Visual C# 2012


Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de