Pregunta

¿Hay un " fácil " ¿Cómo seleccionar un archivo O una carpeta desde el mismo cuadro de diálogo?

En muchas aplicaciones que creo, permito tanto los archivos como las carpetas como entrada. Hasta ahora, siempre termino creando un interruptor para alternar entre los cuadros de diálogo de selección de archivos o carpetas o solo con la funcionalidad de arrastrar y soltar.

Dado que esto parece algo tan básico, me imagino que esto se ha creado antes, pero googlear no da como resultado mucha información. Por lo tanto, parece que tendría que comenzar desde cero y crear un Diálogo de selección personalizado, pero prefiero no presentar ningún problema reinventando la rueda para una tarea tan trivial.

¿Alguien algún consejo o soluciones existentes?

Para mantener la interfaz de usuario coherente, sería bueno si es posible extender OpenFileDialog (o FolderBrowserDialog).

¿Fue útil?

Solución

Técnicamente, es posible. El cuadro de diálogo de shell utilizado por FolderBrowseDialog tiene la capacidad de devolver archivos y carpetas. Desafortunadamente, esa capacidad no está expuesta en .NET. Ni siquiera el reflejo puede tocar el indicador de opción requerido.

Para que funcione, tendría que P / Invocar SHBrowseForFolder () con el indicador BIF_BROWSEINCLUDEFILES activado en BROWSEINFO.ulFlags (valor = 0x4000). El P / Invoke es valiente, es mejor copiar y pegar el código de otra fuente o la clase FolderBrowseDialog en sí con la ayuda de Reflector.

Otros consejos

En base a los consejos anteriores, encontré un código de trabajo que utiliza el cuadro de diálogo estándar del Explorador de carpetas en la siguiente ubicación: http://topic.csdn.net/t/20020703/05/845468.html

La clase para el diálogo extendido del explorador de carpetas

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 

El código para implementar el diálogo extendido

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

Puede usar OpenFileDialog estándar para seleccionar una carpeta. Aquí hay un artículo en CodeProject que demostró una forma de hacerlo ( http: // www. codeproject.com/KB/dialog/OpenFileOrFolderDialog.aspx ).

Ya está hecho. Puede usar FolderBrowserDialogEx - una derivada reutilizable del FolderBrowserDialog incorporado. Este le permite escribir una ruta, incluso una ruta UNC. Puede buscar carpetas o archivos + carpetas. Puede buscar computadoras o impresoras con él. Basado en el FBD incorporado, pero ... mejor. Mas flexible. Si hace clic en una carpeta en la GUI, la ruta aparece en el cuadro de texto. Si ingresa una ruta, la carpeta se activa. Muchas opciones que le faltan al diálogo incorporado.

Código fuente completo. Gratis. Licencia pública de MS.

 FolderBrowserDialogEx

Código para 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, no hay nada en .NET Framework que lo haga listo para usar.

Los cuadros de diálogo del archivo .NET se derivan de CommonDialog :

  

Se requieren clases heredadas para   implementar RunDialog invocando   ShowDialog para crear un común específico   caja de diálogo. Las clases heredadas pueden   anular HookProc para implementar   gancho de cuadro de diálogo específico   funcionalidad.

Todos los cuadros de diálogo integrados utilizan las API de shell que corresponden a su acción, PrintDialog, OpenFileDialog, SaveFileDialog, etc. ...

Lo más probable es que tenga que construir manualmente esta funcionalidad.

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

aquí está el enlace gerat si cambia en esta muestra

  bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;

para

  bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;

obtendrás lo que quieres

Si desea mostrar solo tipos de archivos específicos, los siguientes el artículo (con el código fuente en C #) puede ayudarlo:

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

También explica las otras opciones que están disponibles para "personalizar" el cuadro de diálogo FolderBrowser,

esto le permitirá seleccionar carpetas usando OpenFileDialog

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

Los Diálogos de Ookii implementan un diálogo de explorador de carpetas que permite ambos archivos o carpetas como entrada, y está disponible para Windows Forms y WPF.

ingrese la descripción de la imagen aquí

  

Ookii.Dialogs.Wpf

     

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


  

Ookii.Dialogs.WinForms

     

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top