Wählen Sie entweder eine Datei oder einen Ordner aus dem gleichen Dialog in .NET
-
06-07-2019 - |
Frage
Gibt es eine „einfache“ Art und Weise entweder eine Datei oder einen Ordner aus dem gleichen Dialog zu wählen?
In vielen Anwendungen Ich erstelle ich für beide Dateien oder Ordner als Eingabe ermöglichen. Bis jetzt habe ich immer am Ende einen Schalter zu schaffen zwischen Datei- oder Ordnerauswahldialogen zu wechseln oder Stick mit Drag-and-Drop-Funktionalität nur.
Da dies eine so einfache Sache scheint sich vorstellen würde ich dieses vorher erstellt wurde, aber googeln in viel Information führt nicht. So sieht es aus wie ich brauchen würde, von Grund auf neu starten und eine individuelle Auswahl Dialog erstellen, aber ich eher keine Probleme einführen, indem das Rad für eine solche triviale Aufgabe neu zu erfinden.
jemand irgendwelche Tipps oder bestehende Lösungen?
, um die UI konsistent zu halten wäre es schön, wenn es möglich ist, den Openfiledialog (oder die Folder) zu verlängern.
Lösung
Technisch ist es möglich. Der Shell-Dialog verwendet von FolderBrowseDialog hat die Fähigkeit, beiden Dateien und Ordner zurückzukehren. Leider ist diese Fähigkeit nicht in .NET ausgesetzt. Nicht einmal Reflexion kann die gewünschte Option Flag stecken.
Um es funktioniert, Sie zu P haben würden / Invoke SHBrowseForFolder () mit dem BIF_BROWSEINCLUDEFILES Flagge gedreht in BROWSEINFO.ulFlags auf (Wert = 0x4000). Die P / Invoke ist grobkörnig, es am besten ist, den Code von eine weitere Quelle oder die FolderBrowseDialog Klasse selbst mit Reflector Hilfe.
Andere Tipps
Basierend auf den oben genannten Tipps fand ich einig Arbeitscode, den den Standard-Ordner-Browser-Dialog an folgenden Stelle verwendet: http://topic.csdn.net/t/20020703/05/845468.html
Die Klasse für den erweiterten Ordner-Browser-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 des erweiterten Dialog zu implementieren
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
Sie können die Standard-Openfiledialog verwenden, um einen Ordner auszuwählen. Hier ist ein Artikel in Codeproject, die eine Art und Weise gezeigt, es zu tun ( http: // www. codeproject.com/KB/dialog/OpenFileOrFolderDialog.aspx ).
Es ist getan worden. Sie können verwenden FolderBrowserDialogEx - ein wiederverwendbares Derivat der Einbau-Folder. Dieser ermöglicht es Ihnen, einen Weg zu geben, auch einen UNC-Pfad. Sie können für Ordner oder Dateien + Ordner durchsuchen. Sie können für Computer oder Drucker mit ihm suchen. Auf der Grundlage des integrierten in FBD, aber ... besser. Flexibler. Wenn Sie einen Ordner in der GUI klicken, wird der Pfad in dem Textfeld ein. Wenn Sie in einem Pfad eingeben, wird der Ordner activatied. Es gibt viele Möglichkeiten der integrierten Dialog fehlt.
Der vollständige Quellcode. Kostenlos. MS-Public-Lizenz.
-Code zu verwenden, um es:
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, gibt es nichts in dem .NET-Framework, das dies tut aus dem Kasten heraus.
Die .NET-Dateidialoge stammen aus Common
Geerbte Klassen sind erforderlich, um implementieren RunDialog durch den Aufruf Showdialog eine spezifische gemeinsame erstellen Dialogbox. Geerbte Klassen können außer Kraft setzen HookProc zu implementieren Spezifisches Dialogfeld hook Funktionalität.
Alle integrierten in Dialogen verwenden, um die Shell-API, die ihre Aktion entsprechen, Printdialog, Openfile, Savefiledialog, etc ...
Sie würden höchstwahrscheinlich müssen manuell diese Funktionalität bauen.
http://www.pinvoke.net/default.aspx/shell32.shbrowseforfolder
Hier ist gerat Link, wenn Sie in diesem Beispiel
ändern bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;
für
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;
Sie bekommen, was Sie wollen
Wenn Sie möchten, dass nur bestimmte Dateitypen anzuzeigen, die folgenden Artikel (mit Quellcode in C #) können Sie:
Es erklärt auch die anderen Optionen, die für „Customizing“ der Folderbrowser Dialog zur Verfügung stehen,
Dies ermöglicht es Ihnen, Ordner auswählen mit Openfile
openFileDialog1.CheckFileExists = false;
openFileDialog1.ValidateNames = false;
Die Ookii Dialoge einen Ordner-Browser-Dialog, der für beide erlauben implementieren Dateien oder Ordner als Eingabe und ist für Windows Forms und WPF zur Verfügung.
Ookii.Dialogs.Wpf
Ookii.Dialogs.WinForms