{"id":55000021,"date":"2016-02-01T00:00:00","date_gmt":"2024-04-25T16:18:20","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=21"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Von_VBA_zu_C_Dateidialoge","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Von_VBA_zu_C_Dateidialoge\/","title":{"rendered":"Von VBA zu C#: Dateidialoge"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg05.met.vgwort.de\/na\/dde32dba1bbb4cc8a42358f9cce96019\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Unter VBA musste man schon einigen Zusatzcode inklusive Api-Deklarationen zu seinem Projekt hinzuf&uuml;gen, um Dialoge etwa zum Ausw&auml;hlen einer zu &ouml;ffnenden Datei, eines Verzeichnisses oder zur Angabe eines Dateinamens zum Speichern anzuzeigen. Unter .NET gibt es dazu nat&uuml;rlich eine vorgefertigte Klasse, die alle notwendigen Funktionen liefert. Der vorliegende Artikel zeigt, wie Sie diese Dialoge anzeigen und die damit ermittelten Daten nutzen k&ouml;nnen.<\/b><\/p>\n<p>Die folgenden Beispiele verwenden eine WPF-Anwendung unter C#.<\/p>\n<h2>Dateien ausw&auml;hlen per Klasse<\/h2>\n<p>Unter VBA gibt es verschiedene Varianten, um beispielsweise einen <b>Datei &ouml;ffnen<\/b>-Dialog anzuzeigen. Per API, &uuml;ber die versteckte Wizhook-Klasse oder auch mit der entsprechenden Klasse der Office-Bibliothek. Alle L&ouml;sungen hatten Vor- und Nachteile, aber wirklich perfekt war keine davon.<\/p>\n<p>Unter .NET und in unserem Fall unter C# gibt es eine Klasse namens <b>OpenFileDialog<\/b>. Diese ist Bestandteil des Namespaces <b>Microsoft.Win32<\/b>, den Sie der Klasse per <b>using<\/b>-Anweisung bekannt machen:<\/p>\n<pre>using Microsoft.Win32;<\/pre>\n<p>Danach k&ouml;nnen Sie bereits auf die <b>OpenFileDialog<\/b>-Klasse zugreifen. Dazu legen wir ein WPF-Formular an, das wie in Bild 1 aussieht. Das Textfeld hei&szlig;t <b>txtDateiname<\/b>, die Schaltfl&auml;che <b>btnDateiAuswaehlen<\/b>. F&uuml;r die Schaltfl&auml;che hinterlegen wir die folgende Ereignisprozedur:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_002.png\" alt=\"Entwurf des Fensters zum Ausw&auml;hlen einer Datei\" width=\"550\" height=\"290,44\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Entwurf des Fensters zum Ausw&auml;hlen einer Datei<\/span><\/b><\/p>\n<pre>private void btnDateiAuswaehlen_Click(object sender, \r\n         RoutedEventArgs e) {\r\n     OpenFileDialog openFileDialog = new OpenFileDialog();\r\n     if (openFileDialog.ShowDialog()== true) {\r\n         txtDateiname.Text = openFileDialog.FileName;\r\n     }\r\n}<\/pre>\n<p>Diese erstellt zun&auml;chst ein neues Objekt auf Basis der Klasse <b>OpenFileDialog<\/b>. Im folgenden Schritt rufen wir den <b>Datei &ouml;ffnen<\/b>-Dialog mit der Funktion <b>ShowDialog <\/b>auf. Diese zeigt den <b>Datei &ouml;ffnen<\/b>-Dialog an und erwartet die Eingabe des Benutzers (siehe Bild 2). Die Funktion liefert als Ergebnis einen Boolean-Wert zur&uuml;ck, den die <b>if<\/b>-Anweisung auswertet. Lautet das Ergebnis <b>true<\/b>, hat der Benutzer eine Datei ausgew&auml;hlt und wir k&ouml;nnen diese &uuml;ber die Eigenschaft <b>FileName <\/b>des <b>OpenFileDialog<\/b>-Objekts auslesen und als Text des Textfeldes <b>txtDateiname <\/b>eintragen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_001.png\" alt=\"Ein einfacher Datei &ouml;ffnen-Dialog\" width=\"650\" height=\"454,5558\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Ein einfacher Datei &ouml;ffnen-Dialog<\/span><\/b><\/p>\n<p>Den Wert <b>false <\/b>liefert die Funktion nur dann zur&uuml;ck, wenn der Benutzer den Dialog mit der <b>Schlie&szlig;en<\/b>-Schaltfl&auml;che oben rechts oder mit der <b>Abbrechen<\/b>-Schaltfl&auml;che unten rechts beendet.<\/p>\n<h2>Eigenschaften des OpenFileDialog-Objekts<\/h2>\n<p>Die Klasse besitzt nat&uuml;rlich einige Eigenschaften, mit denen Sie das Aussehen des Dialogs und auch seine Funktion beeinflussen k&ouml;nnen. Hier ist eine Liste der wichtigsten Eigenschaften samt Kurzbeschreibung &#8211; weiter unten schauen wir uns Beispiele zu den wichtigsten Eigenschaften an:<\/p>\n<ul>\n<li><b>CheckFileExists<\/b>: Boolean-Wert, der angibt, ob das Vorhandensein der gew&auml;hlten Datei gepr&uuml;ft werden soll. Der Wert <b>false <\/b>l&auml;sst auch die Angabe nicht vorhandener Dateien zu, der Wert <b>true <\/b>liefert eine Meldung, wenn eine nicht vorhandene Datei gew&auml;hlt wird (Standardwert: <b>true<\/b>) <\/li>\n<li><b>CustomPlaces<\/b>: Spezielle Ordner zus&auml;tzlich zu den Favoriten-Ordnern anzeigen<\/li>\n<li><b>DereferenceLinks<\/b>: Legt fest, ob bei der Auswahl einer Dateiverkn&uuml;pfung die Verkn&uuml;pfung selbst zur&uuml;ckgegeben werden soll (in der Regel eine <b>.lnk<\/b>-Datei) oder der Pfad zu der verkn&uuml;pften Datei.<\/li>\n<li><b>FileName<\/b>: Liefert den Dateinamen der gew&auml;hlten Datei zur&uuml;ck. <\/li>\n<li><b>FileNames<\/b>: Liefert ein Array mit den Dateinamen der gew&auml;hlten Dateien zur&uuml;ck. Sowohl <b>FileName <\/b>als auch <b>FileNames <\/b>funktionieren bei der Einfachauswahl als auch bei der Mehrfachauswahl (siehe Eigenschaft <b>MultiSelect<\/b>).<\/li>\n<li><b>FileOk<\/b>: Dies ist ein Ereignis, das ausgel&ouml;st wird, wenn der Benutzer die Schaltfl&auml;che <b>&Ouml;ffnen<\/b> des <b>Datei &ouml;ffnen<\/b>-Dialogs bet&auml;tigt hat.<\/li>\n<li><b>Filter<\/b>: Erwartet einen Ausdruck, der die zu filternden Dateien angibt. Beispiel: <b>Access-Datenbanken (*.mdb, *.accdb)|*.mdb;*.accdb|Alle Dateien (*.*)|*.*<\/b><\/li>\n<li><b>FilterIndex<\/b>: Legt fest, welcher <b>Filter<\/b>-Eintrag angezeigt werden soll (<b>1 <\/b>f&uuml;r den ersten Eintrag, <b>2 <\/b>f&uuml;r den zweiten und so weiter)<\/li>\n<li><b>InitialDirectory<\/b>: Gibt das beim Einblenden des Dialogs anzuzeigende Verzeichnis an, entweder als Zeichenkette mit f&uuml;hrendem @-Zeichen (<b>@&#8221;c:\\&#8221;<\/b>) oder als Ausdruck, zum Beispiel <b>AppDomain.CurrentDomain.BaseDirectory <\/b>f&uuml;r das Verzeichnis der aktuellen Anwendung.<\/li>\n<li><b>MultiSelect<\/b>: <b>Boolean<\/b>-Eigenschaft, die festlegt, ob nur eine (<b>false<\/b>) oder mehrere Dateien gleichzeitig ausgew&auml;hlt werden k&ouml;nnen (<b>true<\/b>).<\/li>\n<li><b>SafeFileName<\/b>: Liefert den Dateinamen ohne Verzeichnis.<\/li>\n<li><b>SafeFileNames<\/b>: Liefert bei Mehrfachauswahl die Dateinahmen ohne Verzeichnis.<\/li>\n<li><b>ShowDialog<\/b>: Zeigt den Dialog an und liefert den Wert <b>true<\/b> zur&uuml;ck, wenn der Benutzer den Dialog mit der <b>&Ouml;ffnen<\/b>-Schaltfl&auml;che schlie&szlig;t.<\/li>\n<li><b>Title<\/b>: Legt den Fenstertitel fest.<\/li>\n<\/ul>\n<h2>Mehrere Dateien ermitteln<\/h2>\n<p>Wenn Sie mit der <b>OpenFileDialog<\/b>-Klasse nicht nur eine, sondern gegebenenfalls auch einmal mehrere Dateien gleichzeitig ermitteln m&ouml;chten, bedarf es nur weniger &Auml;nderungen (siehe Listing 1). Dazu stellen Sie zun&auml;chst einmal den Wert der Eigenschaft <b>MultiSelect <\/b>der Objektvariablen <b>openFileDialog <\/b>auf den Wert <b>true <\/b>ein. Danach zeigen Sie den Dialog wie gewohnt mit der Methode <b>ShowDialog <\/b>an.<\/p>\n<pre>private void btnDateienAuswaehlen_Click(object sender, RoutedEventArgs e) {\r\n     OpenFileDialog openFileDialog = new OpenFileDialog();\r\n     openFileDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;\r\n     openFileDialog.Multiselect = true;\r\n     if (openFileDialog.ShowDialog() == true) {\r\n         foreach(string filename in openFileDialog.FileNames) {\r\n             lstDateinamen.Items.Add(filename);\r\n         }\r\n         txtDateiname.Text = openFileDialog.FileName;\r\n     }\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Einlesen mehrerer Dateinamen per OpenFileDialog<\/span><\/b><\/p>\n<p>Hat der Benutzer die gew&uuml;nschten Dateien ausgew&auml;hlt und die <b>&Ouml;ffnen<\/b>-Schaltfl&auml;che bet&auml;tigt (siehe Bild 3), gehen wir allerdings etwas anders vor als bei einer einzigen Datei. In diesem Fall soll die Methode n&auml;mlich eine <b>foreach<\/b>-Schleife &uuml;ber alle <b>string<\/b>-Objekte der Auflistung <b>FileNames <\/b>des <b>OpenFileDialog<\/b>-Objekts durchlaufen. Innerhalb der Schleife f&uuml;gt die Methode der Auflistung <b>Items <\/b>des Listenfeldes namens <b>lstDateinamen <\/b>einen neuen Eintrag mit der <b>Add<\/b>-Methode hinzu.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_004.png\" alt=\"Markieren mehrerer Dateien gleichzeitig\" width=\"550\" height=\"336,6754\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Markieren mehrerer Dateien gleichzeitig<\/span><\/b><\/p>\n<p>Das Ergebnis sieht wie in Bild 4 aus. Der Methode haben wir noch eine weitere Anweisung hinzugef&uuml;gt, welche den Wert der Eigenschaft <b>FileName <\/b>in das Textfeld <b>txtDateiname <\/b>eintr&auml;gt. Damit zeigen wir, dass auch bei der Einstellung <b>MultiSelect = true <\/b>der erste Eintrag &uuml;ber die <b>FileName<\/b>-Eigenschaft ermittelt werden kann.<\/p>\n<p class=\"image\"><img loading=\"lazy\" decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_005.png\" alt=\"Anzeige der Dateien im Listenfeld\" width=\"600\" height=\"162\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Anzeige der Dateien im Listenfeld<\/span><\/b><\/p>\n<h2>Textdatei einlesen<\/h2>\n<p>Wenn wir schon Dateien ausw&auml;hlen, k&ouml;nnen wir deren Inhalt auch direkt einmal in ein Textfeld einlesen &#8211; zumindest, wenn es sich um eine Textdatei handelt.<\/p>\n<p>Dazu verwenden wir die Schaltfl&auml;che <b>btnDateiEinlesen<\/b>, welche die Methode aus Listing 2 ausl&ouml;st. Wir wollen an dieser Stelle gleich ein Beispiel f&uuml;r einen Filter liefern. Der <b>&Ouml;ffnen<\/b>-Dialog soll entweder nur Dateien mit der Dateiendung <b>.txt<\/b>, mit der Endung <b>.xml <\/b>oder alle Dateien anzeigen (<b>*.*<\/b>) &#8211; siehe Bild 5. Dazu geben wir der Eigenschaft <b>Filter <\/b>einen entsprechenden Ausdruck mit und stellen den zu Beginn anzuzeigenden Filtereintrag mit der Eigenschaft <b>FilterIndex <\/b>ein.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_006.png\" alt=\"Einlesen von Text- oder XML-Dateien per Filter\" width=\"500\" height=\"253,8354\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Einlesen von Text- oder XML-Dateien per Filter<\/span><\/b><\/p>\n<p>Nach dem Anzeigen des <b>&Ouml;ffnen<\/b>-Dialogs und der Auswahl der Datei speichert die Methode den Dateinamen in der Variablen <b>dateiname<\/b>. Dann erstellt sie ein neues Objekt des Typs <b>StreamReader <\/b>und &uuml;bergibt dem Konstruktor den Dateinamen. Die Methode <b>ReadToEnd <\/b>ermittelt schlie&szlig;lich den Inhalt der Textdatei und tr&auml;gt diesen in das Textfeld <b>txtDateiinhalt <\/b>ein. Der Dateiname landet schlie&szlig;lich noch im Textfeld <b>txtDateiname<\/b>. Das Ergebnis sieht dann wie in Bild 6 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_007.png\" alt=\"Das Beispielformular nach dem Einlesen einer XML-Datei\" width=\"600\" height=\"238,5542\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Das Beispielformular nach dem Einlesen einer XML-Datei<\/span><\/b><\/p>\n<h2>Ereignis nach Auswahl ausl&ouml;sen<\/h2>\n<p>Die Klasse <b>OpenFileDialog <\/b>bietet auch ein Ereignis an, das Sie implementieren k&ouml;nnen. Dazu legen wir eine neue Schaltfl&auml;che namens <b>btnEreignisFileOk <\/b>an. Die dadurch ausgel&ouml;ste Methode finden Sie in Listing 3. Diese zeigt wieder ein <b>OpenFileDialog<\/b>-Fenster an. Diesmal f&uuml;gt sie jedoch der Eigenschaft <b>FileOk <\/b>den Namen der auszul&ouml;senden Methode hinzu, n&auml;mlich <b>OpenFileDialog1_FileOk<\/b>. Dazu verwenden wir den <b>+=<\/b>-Operator. Nach der Eingabe dieses Operators bietet Visual Studio an, per <b>Tabulator<\/b>-Taste automatisch den Wert <b>OpenFileDialog1_FileOk <\/b>hinzuzuf&uuml;gen und die entsprechende Ereignis-Methode anzulegen, was wir dankend annehmen. Damit wir diese f&uuml;r das Objekt <b>OpenFileDialog1 <\/b>implementieren k&ouml;nnen, m&uuml;ssen wir die entsprechende Objektvariable diesmal au&szlig;erhalb der Methode deklarieren, welche die Ereigniseigenschaft f&uuml;llt:<\/p>\n<pre>private void btnEreignisFileOK_Click(object sender, RoutedEventArgs e) {\r\n     openFileDialog1 = new OpenFileDialog();\r\n     openFileDialog1.FileOk += OpenFileDialog1_FileOk;\r\n     if (openFileDialog1.ShowDialog() == true) {\r\n         txtDateiname.Text = openFileDialog1.FileName;\r\n     }\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Anzeigen eines OpenFileDialog-Dialogs, der eine Ereignisprozedur ausl&ouml;sen soll<\/span><\/b><\/p>\n<pre>static OpenFileDialog openFileDialog1;<\/pre>\n<p>Die beim Anklicken der Schaltfl&auml;che <b>&Ouml;ffnen <\/b>des <b>&Ouml;ffnen<\/b>-Dialogs ausgel&ouml;ste Methode <b>OpenFileDialog1_FileOk <\/b>sieht dann wie folgt aus:<\/p>\n<pre>private void OpenFileDialog1_FileOk(object sender, \r\n         CancelEventArgs e) {\r\n     MessageBox.Show(\"Markierte Datei: \" + \r\n         openFileDialog1.FileName);\r\n}<\/pre>\n<p>Sie soll lediglich zum entsprechenden Zeitpunkt ein Meldungsfenster einblenden, welches den Namen der gew&auml;hlten Datei ausgibt.<\/p>\n<h2>Zus&auml;tzliche Ordner: CustomPlaces<\/h2>\n<p>F&uuml;r das <b>CustomPlaces<\/b>-Objekt k&ouml;nnen Sie mit der <b>Add<\/b>-Methode zus&auml;tzliche Ordner in der Art hinzuf&uuml;gen, wie es mit den Favoriten-Ordnern geschieht. Die folgenden drei Anweisungen zeigen, wie dies gelingt:<\/p>\n<pre>...\r\nopenFileDialog.CustomPlaces.Add(\r\n     FileDialogCustomPlaces.Cookies);\r\nopenFileDialog.CustomPlaces.Add(\r\n     FileDialogCustomPlaces.Desktop);\r\nopenFileDialog.CustomPlaces.Add(\r\n     FileDialogCustomPlaces.SendTo);\r\n...<\/pre>\n<p>Bild 7 zeigt, wie ein um alle zus&auml;tzlichen Ordner erweitertes <b>Datei &ouml;ffnen<\/b>-Fenster aussieht. Die m&ouml;glichen Optionen finden Sie hier:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_003.png\" alt=\"Per CustomPlaces hinzugef&uuml;gte Ordner\" width=\"600\" height=\"502,288\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Per CustomPlaces hinzugef&uuml;gte Ordner<\/span><\/b><\/p>\n<ul>\n<li><b>Contacts<\/b>: Kontakte-Ordner des aktuellen Benutzers<\/li>\n<li><b>Cookies<\/b>: Internet-Cookies des aktuellen Benutzers<\/li>\n<li><b>Desktop<\/b>: Desktop-Ordner des aktuellen Benutzers<\/li>\n<li><b>Documents<\/b>: Dokumente-Ordner<\/li>\n<li><b>Favorites<\/b>: Favoriten-Ordner<\/li>\n<li><b>LocalApplicationData<\/b>: Anwendungsdaten des aktuellen Benutzers<\/li>\n<li><b>Music<\/b>: Musik-Ordner<\/li>\n<li><b>Pictures<\/b>: Bilder-Ordner<\/li>\n<li><b>ProgramFiles<\/b>: Programme-Ordner<\/li>\n<li><b>ProgramFilesCommon<\/b>: Gemeinsame Dateien<\/li>\n<li><b>Programs<\/b>: Programme-Ordner des Startmen&uuml;s<\/li>\n<li><b>RoamingApplicationData<\/b>: Ordner \\AppData\\Roaming des aktuellen Benutzers<\/li>\n<li><b>SendTo<\/b>: M&ouml;gliche Ziele zum Senden von Dateien<\/li>\n<li><b>StartMenu<\/b>: Startmen&uuml; des aktuellen Benutzers<\/li>\n<li><b>Startup<\/b>: Autostart-Ordner<\/li>\n<li><b>System<\/b>: Systemdateien<\/li>\n<li><b>Templates<\/b>: Vorlagenordner<\/li>\n<\/ul>\n<h2>Benutzerdefinierte Ordner hinzuf&uuml;gen<\/h2>\n<p>Auf &auml;hnliche Art k&ouml;nnen Sie auch selbst definierte Ordner im <b>Datei &ouml;ffnen<\/b>-Dialog anbieten, wie in der durch die Schaltfl&auml;che <b>btnBenutzerdefinierteOrdner<\/b> ausgel&ouml;sten Methode aus Listing 4.<\/p>\n<pre>private void btnBenutzerdefinierteOrdner_Click(object sender, RoutedEventArgs e) {\r\n     OpenFileDialog openFileDialog = new OpenFileDialog();\r\n     string verzeichnis = @\"c:\\Windows\\System32\";\r\n     FileDialogCustomPlace customPlace = new FileDialogCustomPlace(verzeichnis);\r\n     openFileDialog.CustomPlaces.Add(customPlace);\r\n     if (openFileDialog.ShowDialog() == true) {\r\n         txtDateiname.Text = openFileDialog.FileName;\r\n     }\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: OpenFileDialog-Fenster mit einem benutzerdefinierten Ordner anzeigen<\/span><\/b><\/p>\n<p>Dazu erstellen Sie zun&auml;chst ein neues Objekt des Typs <b>FileDialogCustomPlace <\/b>und speichern den Verweis in einer Variablen namens <b>customPlace<\/b>.<\/p>\n<p>Als Parameter f&uuml;r den Konstruktor &uuml;bergeben Sie dabei die Angabe des Verzeichnisses, das angezeigt werden soll. Schlie&szlig;lich h&auml;ngen Sie das <b>customPlace<\/b>-Objekt mit der <b>Add<\/b>-Methode an die Auflistung <b>CustomPlaces <\/b>des <b>OpenFileDialog<\/b>-Objekts an.<\/p>\n<p>Das Ergebnis sehen Sie in Bild 8. Der neue Ordner ist unter dem Eintrag <b>vshost32.exe <\/b>abgelegt. Dies ist der Name der Datei, welche den Ordner hinzugef&uuml;gt hat, in diesem Fall beim Debuggen. Wenn Sie die Anwendung sp&auml;ter &uuml;ber das Erstellen-Men&uuml; erstellen, erscheint dort der Name der jeweiligen <b>.exe<\/b>-Datei.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_008.png\" alt=\"Benutzerdefinierter Ordner\" width=\"500\" height=\"274,0586\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Benutzerdefinierter Ordner<\/span><\/b><\/p>\n<h2>SaveFileDialog<\/h2>\n<p>Der mit der Klasse <b>OpenFileDialog <\/b>hervorgerufene Dialog erwartet in der Regel die Auswahl einer vorhandenen Datei. Gelegentlich m&ouml;chten Sie aber vielleicht auch mal einen Dialog zum Ermitteln einer zu speichernden Datei anzeigen. Auch daf&uuml;r liefert die <b>Win32<\/b>-Bibliothek eine entsprechende Klasse namens <b>SaveFileDialog<\/b>. Die Vorgehensweise ist in den meisten F&auml;llen &auml;hnlich wie bei der <b>OpenFileDialog<\/b>-Klasse &#8211; mit dem Unterschied, dass Sie eine andere Klasse verwenden. <b>ShowDialog <\/b>blendet den <b>Speichern unter<\/b>-Dialog ein, die <b>FileName<\/b>-Eigenschaft liefert den Namen der ausgew&auml;hlten oder eingegebenen Datei:<\/p>\n<pre>private void btnDateiSpeichern_Click(object sender, \r\n         RoutedEventArgs e) {\r\n     SaveFileDialog saveFileDialog = new SaveFileDialog();\r\n     if (saveFileDialog.ShowDialog() == true) {\r\n         this.txtDateiname.Text = saveFileDialog.FileName;\r\n     }\r\n}<\/pre>\n<p>Es gibt lediglich einige speziell f&uuml;r die <b>SaveFileDialog<\/b>-Klasse vorgesehene Eigenschaften:<\/p>\n<ul>\n<li><b>AddExtension<\/b>: F&uuml;gt eine Dateierweiterung hinzu.<\/li>\n<li><b>CreatePrompt<\/b>: Fragt, ob eine noch nicht vorhandene Datei erzeugt werden soll.<\/li>\n<li><b>DefaultExt<\/b>: Gibt die Standarddateierweiterung an.<\/li>\n<li><b>CheckPathExists<\/b>: Pr&uuml;ft, ob der gew&auml;hlte Pfad existiert.<\/li>\n<\/ul>\n<h2>R&uuml;ckfrage, ob die Datei angelegt werden soll<\/h2>\n<p>Wenn der Benutzer nicht vorhandene Dateien als Zielort f&uuml;r einen Speichervorgang angibt, k&ouml;nnen Sie mit der Eigenschaft <b>CreatePrompt<\/b> festlegen, dass eine entsprechende Meldung angezeigt wird (siehe Bild 9). Dazu stellen Sie die Eigenschaft auf den Wert <b>true <\/b>ein:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_009.png\" alt=\"R&uuml;ckfrage, ob eine noch nicht vorhandene Datei erstellt werden soll\" width=\"550\" height=\"385,965\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: R&uuml;ckfrage, ob eine noch nicht vorhandene Datei erstellt werden soll<\/span><\/b><\/p>\n<pre>saveFileDialog.CreatePrompt = true;<\/pre>\n<h2>Automatische Dateierweiterung<\/h2>\n<p>F&uuml;r den Fall, dass der Benutzer keine Dateierweiterung angibt, k&ouml;nnen Sie eine Standarddateierweiterung angeben. Diese legen Sie mit der Eigenschaft <b>DefaultExt <\/b>fest. Au&szlig;erdem stellen Sie die Eigenschaft <b>AddExtension <\/b>auf den Wert <b>true <\/b>ein:<\/p>\n<pre>saveFileDialog.DefaultExt = \".txt\";\r\nsaveFileDialog.AddExtension = true;<\/pre>\n<h2>Ordner ausw&auml;hlen<\/h2>\n<p>Fehlt noch ein Dialog, mit dem Sie einen Ordner ausw&auml;hlen k&ouml;nnen. Diesen ben&ouml;tigen Sie beispielsweise, wenn Sie eine Reihe von Dateien von A nach B kopieren wollen oder Ihre Anwendung eine oder mehrere Dateien erzeugt und diese unter fest vorgegebenen Namen in einem vom Benutzer gew&auml;hlten Verzeichnis landen sollen. Dazu k&ouml;nnen wir leider nicht die gleiche Bibliothek verwenden, aus der wir auch die beiden Klassen <b>OpenFileDialog <\/b>und <b>SaveFileDialog <\/b>genutzt haben. Stattdessen nehmen wir hier die Bibliothek <b>System.Windows.Forms <\/b>zuhilfe. Diese liefert die Klasse <b>FolderBrowserDialog<\/b>, die Sie wie &uuml;blich deklarieren und instanzieren (siehe Listing 5).<\/p>\n<pre>private void btnVerzeichnisAuswaehlen_Click(object sender, RoutedEventArgs e) {\r\n     System.Windows.Forms.FolderBrowserDialog folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();\r\n     if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {\r\n         this.txtDateiname.Text = folderBrowserDialog.SelectedPath;\r\n     }\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Dialog zur Auswahl von Verzeichnissen anzeigen<\/span><\/b><\/p>\n<p>Die Klasse bietet die Methode <b>ShowDialog<\/b> an, mit der Sie den <b>Ordner suchen<\/b>-Dialog aus Bild 10 anzeigen. Diese liefert allerdings keinen <b>Boolean<\/b>-Wert als Antwort, sondern eine Konstante des Typs <b>DialogResult<\/b>. In diesem Fall wollen wir das gew&auml;hlte Verzeichnis im Textfeld <b>txtDateiname <\/b>anzeigen, wenn der Benutzer die Schaltfl&auml;che <b>OK <\/b>bet&auml;tigt hat, was der Konstanten <b>DialogResult.OK <\/b>entspricht.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_21_010.png\" alt=\"Ordner suchen-Dialog aufrufen\" width=\"550\" height=\"417,2943\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: Ordner suchen-Dialog aufrufen<\/span><\/b><\/p>\n<p>Die Verweise auf die Objekte der Bibliothek <b>System.Windows.Forms <\/b>haben wir diesmal nicht mit der <b>using<\/b>-Anweisung vereinfacht. Dies h&auml;tte zu einem Fehler gef&uuml;hrt, weil dann sowohl <b>System.Windows.Forms <\/b>als auch <b>Microsoft.Win32 <\/b>die Klassen <b>OpenFileDialog <\/b>und <b>SaveFileDialog <\/b>bereitgestellt h&auml;tten. Um dies zu verhindern, k&ouml;nnten Sie auch die folgende Variante der <b>using<\/b>-Direktive nutzen &#8211; und zwar zus&auml;tzlich zu den bereits vorhandenen <b>using<\/b>-Direktiven:<\/p>\n<pre>using OpenFileDialog = Microsoft.Win32.OpenFileDialog;\r\nusing SaveFileDialog = Microsoft.Win32.SaveFileDialog;\r\nusing FolderBrowserDialog = \r\n     System.Windows.Forms.FolderBrowserDialog;<\/pre>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Damit haben Sie die drei Dialoge zum &Ouml;ffnen und Speichern von Dateien sowie zum Ausw&auml;hlen von Verzeichnissen kennen gelernt. Diese k&ouml;nnen Sie nun leicht in eigenen Anwendungen einsetzen.<\/p>\n<p>Im Gegensatz zu VBA stehen die entsprechenden Objekte erfreulicherweise bereits in den einzubindenden Bibliotheken bereit, eine direkte DLL-Nutzung ist so nicht mehr n&ouml;tig.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Unter VBA musste man schon einigen Zusatzcode inklusive Api-Deklarationen zu seinem Projekt hinzuf&uuml;gen, um Dialoge etwa zum Ausw&auml;hlen einer zu &ouml;ffnenden Datei, eines Verzeichnisses oder zur Angabe eines Dateinamens zum Speichern anzuzeigen. Unter .NET gibt es dazu nat&uuml;rlich eine vorgefertigte Klasse, die alle notwendigen Funktionen liefert. Der vorliegende Artikel zeigt, wie Sie diese Dialoge anzeigen und die damit ermittelten Daten nutzen k&ouml;nnen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66012016,662016,44000002,44000001,44000027],"tags":[],"yst_prominent_words":[66062023,66062051,66062047,66062079,66062053,66062096],"class_list":["post-55000021","post","type-post","status-publish","format-standard","hentry","category-66012016","category-662016","category-Benutzeroberflaeche_mit_WPF","category-CGrundlagen","category-Excel_programmieren"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000021","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000021"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000021\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000021"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}