it-swarm.com.de

Wählen Sie entweder eine Datei oder einen Ordner aus demselben Dialog in .NET aus

Gibt es eine "einfache" Möglichkeit, entweder eine Datei OR einen Ordner aus demselben Dialog auszuwählen?

In vielen Apps, die ich erstelle, kann ich sowohl Dateien als auch Ordner als Eingabe zulassen. Bislang habe ich immer einen Schalter zum Wechseln zwischen Datei- oder Ordnerauswahldialogen oder nur mit Drag & Drop-Funktionalität erstellt. 

Da dies so eine grundlegende Sache zu sein scheint, würde ich mir vorstellen, dass dies schon vorher erstellt wurde, aber das Googeln führt nicht zu vielen Informationen. Es sieht also so aus, als müsste ich bei Null anfangen und einen benutzerdefinierten Auswahldialog erstellen, aber ich stelle keine Probleme vor, indem ich das Rad für eine solche triviale Aufgabe neu erfinde.

Jemand irgendwelche Tipps oder bestehende Lösungen?

Um die Benutzeroberfläche konsistent zu halten, wäre es schön, wenn der OpenFileDialog (oder der FolderBrowserDialog) erweitert werden könnte.

31
barry

Technisch ist es möglich. Das von FolderBrowseDialog verwendete Shell-Dialogfeld kann Dateien und Ordner zurückgeben. Leider ist diese Funktion in .NET nicht verfügbar. Nicht einmal eine Reflexion kann das erforderliche Optionsflag setzen.

Damit dies funktioniert, müssen Sie SHBrowseForFolder () mit dem Flag BIF_BROWSEINCLUDEFILES in BROWSEINFO.ulFlags aktivieren (Wert = 0x4000). Das P/Invoke ist grobkörnig. Es ist am besten, den Code aus einer anderen Quelle oder der FolderBrowseDialog-Klasse selbst mit Hilfe von Reflector zu kopieren und einzufügen.

12
Hans Passant

Basierend auf den obigen Tipps habe ich an der folgenden Stelle einen Funktionscode gefunden, der das Standarddialogfeld "Folder Browser" verwendet: http://topic.csdn.net/t/20020703/05/845468.html

Die Klasse für den erweiterten Ordnerbrowser-Dialog

Imports System   
Imports System.Text   
Imports System.Windows.Forms   
Imports System.Runtime.InteropServices   

Public Class DirectoryDialog 
    Public Structure BROWSEINFO 
        Public hWndOwner As IntPtr 
        Public pIDLRoot As Integer 
        Public pszDisplayName As String 
        Public lpszTitle As String 
        Public ulFlags As Integer 
        Public lpfnCallback As Integer 
        Public lParam As Integer 
        Public iImage As Integer 
    End Structure 

    Const MAX_PATH As Integer = 260

    Public Enum BrowseForTypes As Integer 
        Computers = 4096 
        Directories = 1 
        FilesAndDirectories = 16384 
        FileSystemAncestors = 8 
    End Enum 

    Declare Function CoTaskMemFree Lib "ole32" Alias "CoTaskMemFree" (ByVal hMem As IntPtr) As Integer 
    Declare Function lstrcat Lib "kernel32" Alias "lstrcat" (ByVal lpString1 As String, ByVal lpString2 As String) As IntPtr 
    Declare Function SHBrowseForFolder Lib "Shell32" Alias "SHBrowseForFolder" (ByRef lpbi As BROWSEINFO) As IntPtr 
    Declare Function SHGetPathFromIDList Lib "Shell32" Alias "SHGetPathFromIDList" (ByVal pidList As IntPtr, ByVal lpBuffer As StringBuilder) As Integer 
    Protected Function RunDialog(ByVal hWndOwner As IntPtr) As Boolean 

        Dim udtBI As BROWSEINFO = New BROWSEINFO() 
        Dim lpIDList As IntPtr 
        Dim hTitle As GCHandle = GCHandle.Alloc(Title, GCHandleType.Pinned) 
        udtBI.hWndOwner = hWndOwner 
        udtBI.lpszTitle = Title 
        udtBI.ulFlags = BrowseFor 
        Dim buffer As StringBuilder = New StringBuilder(MAX_PATH) 
        buffer.Length = MAX_PATH 
        udtBI.pszDisplayName = buffer.ToString() 
        lpIDList = SHBrowseForFolder(udtBI) 
        hTitle.Free() 
        If lpIDList.ToInt64() <> 0 Then 
            If BrowseFor = BrowseForTypes.Computers Then 
                m_Selected = udtBI.pszDisplayName.Trim() 
            Else 
                Dim path As StringBuilder = New StringBuilder(MAX_PATH) 
                SHGetPathFromIDList(lpIDList, path) 
                m_Selected = path.ToString() 
            End If 
            CoTaskMemFree(lpIDList) 
        Else 
            Return False 
        End If 
        Return True 
    End Function 

    Public Function ShowDialog() As DialogResult 
        Return ShowDialog(Nothing) 
    End Function 

    Public Function ShowDialog(ByVal owner As IWin32Window) As DialogResult 
        Dim handle As IntPtr 
        If Not owner Is Nothing Then 
            handle = owner.Handle 
        Else 
            handle = IntPtr.Zero 
        End If 
        If RunDialog(handle) Then 
            Return DialogResult.OK 
        Else 
            Return DialogResult.Cancel 
        End If 
    End Function 

    Public Property Title() As String 
        Get 
            Return m_Title 
        End Get 
        Set(ByVal Value As String) 
            If Value Is DBNull.Value Then 
                Throw New ArgumentNullException() 
            End If 
            m_Title = Value 
        End Set 
    End Property

    Public ReadOnly Property Selected() As String 
        Get 
            Return m_Selected 
        End Get 
    End Property 

    Public Property BrowseFor() As BrowseForTypes
        Get 
            Return m_BrowseFor 
        End Get 
        Set(ByVal Value As BrowseForTypes) 
            m_BrowseFor = Value 
        End Set 
    End Property 

    Private m_BrowseFor As BrowseForTypes = BrowseForTypes.Directories 
    Private m_Title As String = "" 
    Private m_Selected As String = "" 

    Public Sub New() 
    End Sub
End Class 

Der Code zum Implementieren des erweiterten Dialogs

Sub Button1Click(ByVal sender As Object, ByVal e As EventArgs)
    Dim frmd As DirectoryDialog = New DirectoryDialog()
    ' frmd.BrowseFor = DirectoryDialog.BrowseForTypes.Directories   
    ' frmd.BrowseFor = DirectoryDialog.BrowseForTypes.Computers   
    frmd.BrowseFor = DirectoryDialog.BrowseForTypes.FilesAndDirectories   
    frmd.Title = "Select a file or a folder"    
    If frmd.ShowDialog(Me) = DialogResult.OK Then   
        MsgBox(frmd.Selected)   
    End If   
End Sub
7
barry

Es wurde getan. Sie können FolderBrowserDialogEx - Verwenden, eine wiederverwendbare Ableitung des integrierten FolderBrowserDialogs. Hier können Sie einen Pfad eingeben, sogar einen UNC-Pfad. Sie können nach Ordnern oder Dateien + Ordnern suchen. Sie können damit nach Computern oder Druckern suchen. Basierend auf der eingebauten FBS, aber ... besser. Flexibler. Wenn Sie in der GUI auf einen Ordner klicken, wird der Pfad im Textfeld angezeigt. Wenn Sie einen Pfad eingeben, wird der Ordner aktiviert. Viele Optionen fehlen dem eingebauten Dialog. 

Vollständiger Quellcode. Kostenlos. MS-Public Lizenz.

FolderBrowserDialogEx http://www.freeimagehosting.net/uploads/bfbab6cea5.png

Code, um es zu benutzen: 

     var dlg1 = new Ionic.Utils.FolderBrowserDialogEx();
     dlg1.Description = "Select a folder to extract to:";
     dlg1.ShowNewFolderButton = true;
     dlg1.ShowEditBox = true;
     //dlg1.NewStyle = false;
     dlg1.SelectedPath = txtExtractDirectory.Text;
     dlg1.ShowFullPathInEditBox = true;
     dlg1.RootFolder = System.Environment.SpecialFolder.MyComputer;

     // Show the FolderBrowserDialog.
     DialogResult result = dlg1.ShowDialog();
     if (result == DialogResult.OK)
     {
         txtExtractDirectory.Text = dlg1.SelectedPath;
     }
5
Cheeso

Sie können den Standard-OpenFileDialog verwenden, um einen Ordner auszuwählen. Hier ist ein Artikel in CodeProject, in dem ein Weg aufgezeigt wurde ( http://www.codeproject.com/KB/dialog/OpenFileOrFolderDialog.aspx ).

5
stankovski

http://www.pinvoke.net/default.aspx/Shell32.shbrowseforfolder

hier ist gerat link, wenn Sie in diesem Beispiel ändern

  bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;

zum 

  bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;

sie werden bekommen, was Sie wollen

1
Araym

AFAIK, es gibt nichts im .NET-Framework, das dies aus der Box heraus tut. 

Die .NET-Dateidialoge stammen von CommonDialog :

Geerbte Klassen müssen Ausführen, um RunDialog durch Aufrufen von ShowDialog auszuführen, um ein bestimmtes allgemeines Dialogfeld Zu erstellen. Vererbte Klassen können HookProc überschreiben, um die Spezifische Dialogfeldhakenfunktion Zu implementieren.

1
Mitch Wheat

Alle eingebauten Dialoge verwenden die Shell-APIs, die ihrer Aktion entsprechen, PrintDialog, OpenFileDialog, SaveFileDialog usw.

Sie müssen diese Funktionalität höchstwahrscheinlich manuell erstellen.

1
Tom Anderson

Wenn Sie nur bestimmte Dateitypen anzeigen möchten, kann Ihnen der folgende article (mit Quellcode in C #) helfen: 

http://www.codeproject.com/KB/Shell/csdoesshell1.aspx?fid=14137&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26

Außerdem werden die anderen Optionen erläutert, die zum "Anpassen" des Dialogfelds "FolderBrowser" verfügbar sind.

0
barry

DieOokii-Dialogeimplementieren einen Ordnerbrowser-Dialog, der sowohl Dateien als auch Ordner als Eingabe zulässt und für Windows Forms und WPF verfügbar ist.

 enter image description here

Ookii.Dialogs.Wpf

https://github.com/caioproiete/ookii-dialogs-wpf


Ookii.Dialogs.WinForms

https://github.com/caioproiete/ookii-dialogs-winforms

0
Caio Proiete

dadurch können Sie Ordner mithilfe von OpenFileDialog auswählen

        openFileDialog1.CheckFileExists = false;
        openFileDialog1.ValidateNames = false;
0
Jason P