OpenFileDialog, SaveFileDialog, PickFolderDialog (Single Select) per Interface IFileDialog verwenden

    • VB.NET
    • .NET (FX) 4.5–4.8

    Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von -Franky-.

      OpenFileDialog, SaveFileDialog, PickFolderDialog (Single Select) per Interface IFileDialog verwenden

      Hi@all
      Hier möchte ich Euch zeigen wie Ihr den OpenFileDialog, SaveFileDialog, und PickFolderDialog (alle Single Select) per Interface IFileDialog verwenden könnt. Nun fragen sich wahrscheinlich alle, warum sollte ich diese Dialoge vom Interface IFileDialog verwenden? Die entsprechenden Controls bzw. Klassen zu den im Framework vorhandenen Dialogen verwenden APIs (GetOpenFileName, GetSaveFileName und SHBrowseForFolder), die laut Microsoft ab Windows Vista nicht mehr verwendet werden sollten! Dies ist auch so in der Microsoft Doku zu den APIs zu lesen.

      Die Dialoge vom Interface IFileDialog sind moderner und flexibler als die alten Dialoge per API. Die neuen Dialoge lassen sich ganz einfach mit weiteren Controls erweitern (Customize), Standard Controls anpassen (Caption), und es stehen diverse Events zu Verfügung. Die Bilder zeigen ein paar Dialoge (Customized und Standard). Dieses Beispiel zeigt auch nur Single Select Dialoge. Also man kann nur eine Datei im OpenFileDialog auswählen. Für Multi Select beim OpenFileDialog müsste man das Interface IFileOpenDialog, anstatt IFileDialog oder IFileDialog2, verwenden. Dieses stellt eine Funktion GetResults zur Verfügung das ein Interface IShellItemArray zurückliefert über das man dann auf die einzelnen IShellItem zugreifen kann um an die Namen der Dateien zu kommen. Es gibt noch das Interface IFileSaveDialog. Das stellt noch ein paar weitere Funktionen bereit die man für das Speichern von einer Datei evtl. brauchen könnte. Die Interfaces IFileOpenDialog, IFileSaveDialog und IShellItemArray sind in diesen Beispiel aber nicht vorhanden und können ja selbst eingebaut werden. Was ich noch eingebaut habe, ist eine Sub über die man das FensterHandle des Dialoges ermitteln kann. Mit dem FensterHandle könnte man nun den Dialog Subclassen, die Controls auf dem Dialog enumerieren und diese ebenfalls Subclassen/Manipulieren falls man das möchte. Ein praktisches Beispiel für die neuen Dialoge wäre zB. der PickFolderDialog_Locked. Das ganze ist so programmiert, das ein ausgewählter Ordner nicht verlassen werden kann. Es kann nur der Ordner selber und deren Unterordner besucht und ausgewählt werden. Kann man natürlich auch auf einen OpenFile- oder SaveFileDialog übertragen.

      Das ganze ist wie immer eher Testcode und soll nur zeigen wie es funktioniert. Wie immer werden keine extra Verweise usw. verwendet.
      Bilder
      • Custom_OpenFileDialog.png

        40,14 kB, 926×578, 163 mal angesehen
      • OpenFileDialog.png

        229,28 kB, 915×486, 159 mal angesehen
      • OpenFileDialog_EditorStyle.png

        41,19 kB, 889×568, 142 mal angesehen
      • PickFolderDialog.png

        38,95 kB, 885×486, 132 mal angesehen
      • PickFolderDialog_Locked.png

        33,08 kB, 885×486, 145 mal angesehen
      • SaveFileDialog.png

        35,9 kB, 885×486, 130 mal angesehen
      Dateien
      Mfg -Franky-

      Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „-Franky-“ ()

      In der Datei FileDialog.vb Zeile 203

      VB.NET-Quellcode

      1. If CType(Me.m_FileOpenDialog, IFileDialog2).Show(Form.ActiveForm.Handle) = S_OK Then
      2. bolRet = True
      3. End If


      Form.ActiveForm übernimmt keine aktive Form, und daher wird immer ein Exception geworfen.

      So hingegen gehts

      VB.NET-Quellcode

      1. Dim activeformhandle = Form.ActiveForm.Handle
      2. If CType(Me.m_FileOpenDialog, IFileDialog2).Show(activeformhandle) = S_OK Then
      3. bolRet = True
      4. End If


      Ist bei mir ein komisches Verhalten:

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „exc-jdbi“ ()

      Hi

      Danke für die Info. Wobei ich keine Exception an der Stelle erhalte. Wie auch immer. Ich hatte zuerst auch überlegt ob man der Funktion Show noch einen Parameter verpasst wo man dann halt ein Handle auf eine Form mitgeben kann. Ohne Handle wären die Dialoge sogar nicht modal. Also vllt so in der Art.

      VB.NET-Quellcode

      1. Public Function Show() As Boolean
      2. Return ShowDialog(IntPtr.Zero)
      3. End Function
      4. Public Function Show(Handle As IntPtr) As Boolean
      5. Return ShowDialog(Handle)
      6. End Function
      7. Public Function Show(Window As IWin32Window) As Boolean
      8. Return ShowDialog(Window.Handle)
      9. End Function
      10. Private Function ShowDialog(Handle As IntPtr) As Boolean
      11. Dim bolRet As Boolean = False
      12. m_DialogHwnd = IntPtr.Zero
      13. If m_FileOpenDialog IsNot Nothing Then
      14. If CType(m_FileOpenDialog, IFileDialog2).Show(Handle) = S_OK Then
      15. bolRet = True
      16. End If
      17. End If
      18. m_DialogHwnd = IntPtr.Zero
      19. Return bolRet
      20. End Function


      Mfg -Franky-

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „-Franky-“ ()

      Hi

      Jupp, geht auch. Wobei dann der Dialog nicht mehr modal ist. Möglichkeiten gibt es da ja einige. Ich hätte auch aus einigen Funktionen noch Properties machen können oder das ganze so anpassen, das das mit den Properties/Funktionen der im Framework vorhandenen Dialogen übereinstimmt. Dann könnte man die alten Dialoge einfach gegen die neuen austauschen. Aber ich möchte Euch ja nicht den Spaß nehmen ein bissel selbst noch was dran herum programmieren zu dürfen. ;)
      Mfg -Franky-