質問

「簡単」はありますか同じダイアログからファイルまたはフォルダを選択する方法は?

作成する多くのアプリでは、入力としてファイルまたはフォルダーの両方を許可しています。 これまで、私は常にファイルまたはフォルダー選択ダイアログを切り替えるスイッチを作成するか、ドラッグアンドドロップ機能のみを使用していました。

これは非常に基本的なことなので、これは以前に作成されたと思いますが、グーグルでは多くの情報は得られません。だから、ゼロから始めてカスタム選択ダイアログを作成する必要があるように見えますが、そのような些細なタスクのためにホイールを再発明することで問題を導入するのではありません。

ヒントや既存のソリューションはありますか?

UIの一貫性を保つために、OpenFileDialog(またはFolderBrowserDialog)を拡張できると便利です。

役に立ちましたか?

解決

技術的には可能です。 FolderBrowseDialogで使用されるシェルダイアログには、ファイルとフォルダーの両方を返す機能があります。残念ながら、その機能は.NETでは公開されていません。リフレクションでさえ、必要なオプションフラグを突くことができません。

それを機能させるには、BROWSEINFO.ulFlags(値= 0x4000)でBIF_BROWSEINCLUDEFILESフラグをオンにしてSHBrowseForFolder()をP / Invokeする必要があります。 P / Invokeはザラザラしているので、別のソース、またはReflectorのヘルプ付きのFolderBrowseDialogクラス自体。

他のヒント

上記のヒントに基づいて、次の場所で標準のフォルダーブラウザーダイアログを使用する作業コードを見つけました: http://topic.csdn.net/t/20020703/05/845468.html

拡張フォルダブラウザダイアログのクラス

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 

拡張ダイアログを実装するコード

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

標準のOpenFileDialogを使用して、フォルダーを選択できます。これを行う方法を示したCodeProjectの記事( http:// www。 codeproject.com/KB/dialog/OpenFileOrFolderDialog.aspx )。

完了しました。 FolderBrowserDialogEx を使用できます- 組み込みのFolderBrowserDialogの再利用可能な派生物。これにより、UNCパスなどのパスを入力できます。フォルダー、またはファイルとフォルダーを参照できます。それを使用してコンピューターまたはプリンターを参照できます。組み込みのFBDに基づいていますが、...優れています。より柔軟。 GUIでフォルダーをクリックすると、テキストボックスにパスが表示されます。パスをキー入力すると、フォルダーがアクティブになります。組み込みダイアログにないオプションがたくさん。

完全なソースコード。無料です。 MS-Publicライセンス。

 FolderBrowserDialogEx

使用するコード:

     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、.NETフレームワークにはこれをすぐに実行できるものは何もありません。

.NETファイルダイアログは、 CommonDialog <から派生します

  

継承されたクラスは   呼び出しによってRunDialogを実装する   特定の共通を作成するShowDialog   ダイアログボックス。継承されたクラスは   HookProcをオーバーライドして実装する   特定のダイアログボックスフック   機能。

すべての組み込みダイアログは、アクション、PrintDialog、OpenFileDialog、SaveFileDialogなどに対応するシェルAPIを使用します。

ほとんどの場合、この機能を手動で構築する必要があります。

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

このサンプルで変更した場合、geratリンクはこちら

  bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;

for

  bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;

欲しいものが手に入ります

特定のファイルタイプのみを表示する場合は、次の記事(C#のソースコードを使用)が役立ちます。

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

また、「カスタマイズ」に使用できる他のオプションについても説明します。 FolderBrowserダイアログ、

これにより、OpenFileDialogを使用してフォルダーを選択できます

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

Ookiiダイアログ は、両方を可能にするフォルダブラウザダイアログを実装しますファイルまたはフォルダーを入力として使用し、WindowsフォームおよびWPFで使用できます。

「ここに画像の説明を入力してください」

  

Ookii.Dialogs.Wpf

     

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


  

Ookii.Dialogs.WinForms

     

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top