Domanda

Esiste un " facile " modo di selezionare un file o una cartella dalla stessa finestra di dialogo?

In molte app che creo consento sia i file che le cartelle come input. Fino ad ora finisco sempre per creare un interruttore per alternare tra le finestre di dialogo di selezione di file o cartelle o attenermi solo alla funzionalità di trascinamento della selezione.

Dal momento che sembra una cosa così basilare, immagino che sia stato creato prima, ma cercare su Google non ci sono molte informazioni. Quindi sembra che dovrei ricominciare da zero e creare una finestra di dialogo di selezione personalizzata, ma preferisco non introdurre alcun problema reinventando la ruota per un compito così banale.

Qualcuno ha qualche suggerimento o soluzione esistente?

Per mantenere coerente l'interfaccia utente sarebbe bello se è possibile estendere OpenFileDialog (o FolderBrowserDialog).

È stato utile?

Soluzione

Tecnicamente, è possibile. La finestra di dialogo della shell utilizzata da FolderBrowseDialog ha la capacità di restituire sia file che cartelle. Sfortunatamente, questa funzionalità non è esposta in .NET. Neanche la riflessione può colpire il flag di opzione richiesto.

Per farlo funzionare, dovresti P / Invocare SHBrowseForFolder () con il flag BIF_BROWSEINCLUDEFILES attivato in BROWSEINFO.ulFlags (valore = 0x4000). Il P / Invoke è grintoso, è meglio copiare e incollare il codice da un'altra fonte o la classe FolderBrowseDialog stessa con l'aiuto di Reflector.

Altri suggerimenti

Sulla base dei suggerimenti precedenti ho trovato del codice funzionante che utilizza la finestra di dialogo Browser cartelle standard nella seguente posizione: http://topic.csdn.net/t/20020703/05/845468.html

La classe per la finestra di dialogo estesa del browser delle cartelle

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 

Il codice per implementare la finestra di dialogo estesa

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

È possibile utilizzare OpenFileDialog standard per selezionare una cartella. Ecco un articolo in CodeProject che ha dimostrato un modo per farlo ( http: // www. codeproject.com/KB/dialog/OpenFileOrFolderDialog.aspx ).

È stato fatto. Puoi utilizzare FolderBrowserDialogEx - una derivata riutilizzabile di FolderBrowserDialog incorporato. Questo ti consente di digitare un percorso, anche un percorso UNC. Puoi cercare cartelle o file + cartelle. Puoi cercare computer o stampanti con esso. Basato sull'FBD integrato, ma ... meglio. Più flessibile. Se si fa clic su una cartella nella GUI, il percorso viene visualizzato nella casella di testo. Se si digita un percorso, la cartella viene attivata. Molte opzioni mancano nella finestra di dialogo integrata.

Codice sorgente completo. Gratuito. Licenza MS-Public.

 FolderBrowserDialogEx

Codice per usarlo:

     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;
     }

AFAIK, non c'è nulla nel framework .NET che lo fa immediatamente.

Le finestre di dialogo dei file .NET derivano da CommonDialog :

  

Le classi ereditate sono obbligate a   implementare RunDialog invocando   ShowDialog per creare un comune specifico   la finestra di dialogo. Le classi ereditate possono   sovrascrivere HookProc per implementare   gancio specifico della finestra di dialogo   funzionalità.

Tutte le finestre di dialogo integrate utilizzano le API della shell che corrispondono alla loro azione, PrintDialog, OpenFileDialog, SaveFileDialog, ecc ...

Molto probabilmente dovresti creare manualmente questa funzionalità.

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

ecco il link gerat se cambi in questo esempio

  bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;

per

  bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;

otterrai ciò che vuoi

Se desideri visualizzare solo tipi di file specifici, i seguenti articolo (con codice sorgente in C #) può aiutarti:

http :? //www.codeproject.com/KB/shell/csdoesshell1.aspx fid = 14137 & amp; df = 90 & amp; mpp = 25 & amp; rumore = 3 & amp; sorta = Posizione & amp; view = Quick & amp; fr = 26

Spiega anche le altre opzioni disponibili per " personalizzazione " la finestra di dialogo FolderBrowser,

questo ti permetterà di selezionare le cartelle usando OpenFileDialog

        openFileDialog1.CheckFileExists = false;
        openFileDialog1.ValidateNames = false;

I Ookii Dialogs implementano una finestra di dialogo del browser delle cartelle che consente entrambi file o cartelle come input ed è disponibile per Windows Form e WPF.

inserisci qui la descrizione dell'immagine

  

Ookii.Dialogs.Wpf

     

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


  

Ookii.Dialogs.WinForms

     

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top