web-dev-qa-db-ja.com

ディレクトリを開くダイアログ

次に生成するファイルを保存するディレクトリをユーザーに選択させてください。私はWPFで私はWin32からのOpenFileDialogを使うべきであることを知っています、しかし残念なことにダイアログはファイルを選択することを要求します - 選択せずに単にOKをクリックするならそれは開いたままです。ユーザーにファイルを選択させ、それからパスを取り除いてそれがどのディレクトリに属しているのかを判断させることで、機能を「ハックアップ」することができますが、それはせいぜい直感的ではありません。誰かがこれを以前にやったのを見たことがありますか?

249
Alexandra

これには組み込みの FolderBrowserDialog クラスを使うことができます。 System.Windows.Forms名前空間にあることを気にしないでください。

using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
    System.Windows.Forms.DialogResult result = dialog.ShowDialog();
}

ウィンドウをWPFウィンドウ上でモーダルにしたい場合は、 WPFアプリケーションからFolderBrowserDialogを使用する方法 を参照してください。


編集:普通の、見苦しいWindowsフォームのFolderBrowserDialogより少し気の利いたものが欲しいなら、代わりにVistaダイアログを使うことを可能にするいくつかの選択肢があります。 :

  • Ookii dialogs (.NET 3.5)などのサードパーティ製ライブラリ
  • Windows APIコードパック - シェル

    using Microsoft.WindowsAPICodePack.Dialogs;
    
    ...
    
    var dialog = new CommonOpenFileDialog();
    dialog.IsFolderPicker = true;
    CommonFileDialogResult result = dialog.ShowDialog();
    

    このダイアログは、Windows Vistaより古いオペレーティングシステムでは利用できないので、必ず最初にCommonFileDialog.IsPlatformSupportedを確認してください。

371
Heinzi

私はこのように使用されるUserControlを作成しました:

  <UtilitiesWPF:FolderEntry Text="{Binding Path=LogFolder}" Description="Folder for log files"/>

Xamlのソースはこのようになります。

<UserControl x:Class="Utilities.WPF.FolderEntry"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">
    <DockPanel>
        <Button Margin="0" Padding="0" DockPanel.Dock="Right" Width="Auto" Click="BrowseFolder">...</Button>
        <TextBox Height="Auto" HorizontalAlignment="Stretch" DockPanel.Dock="Right" 
           Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
    </DockPanel>
</UserControl>

そして分離コード

public partial class FolderEntry {
    public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(FolderEntry), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    public static DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(FolderEntry), new PropertyMetadata(null));

    public string Text { get { return GetValue(TextProperty) as string; } set { SetValue(TextProperty, value); }}

    public string Description { get { return GetValue(DescriptionProperty) as string; } set { SetValue(DescriptionProperty, value); } }

    public FolderEntry() { InitializeComponent(); }

    private void BrowseFolder(object sender, RoutedEventArgs e) {
        using (FolderBrowserDialog dlg = new FolderBrowserDialog()) {
            dlg.Description = Description;
            dlg.SelectedPath = Text;
            dlg.ShowNewFolderButton = true;
            DialogResult result = dlg.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK) {
                Text = dlg.SelectedPath;
                BindingExpression be = GetBindingExpression(TextProperty);
                if (be != null)
                    be.UpdateSource();
            }
        }
    }
 }
40
adrianm

私は Ookii dialogs をしばらく使っていますが、WPFにはうまく働きます。

これがダイレクトページです。

http://www.ookii.org/Blog/new_download_ookiidialogs

9
Rafael

カスタムダイアログを作成したくないが、それでも100%WPFの方法を好み、個別のDDL、追加の依存関係、または古いAPIを使用したくない人のために、Save Asダイアログを使用した非常に簡単なハックを思いつきました。

Usingディレクティブは必要ありません。以下のコードをコピーして貼り付けるだけです。

それはまだ非常にユーザーフレンドリーであるべきで、ほとんどの人は決して気付かないでしょう。

このアイデアは、ダイアログのタイトルを変更したり、ファイルを非表示にしたり、作成されたファイル名を非常に簡単に回避したりできるという事実から来ています。

それは確かに大きなハックですが、多分それはあなたの使用法のためにちょうどうまく仕事をするでしょう...

この例では、結果のパスを含むテキストボックスオブジェクトがありますが、必要に応じて関連する行を削除して戻り値を使用することもできます。

// Create a "Save As" dialog for selecting a directory (HACK)
var dialog = new Microsoft.Win32.SaveFileDialog();
dialog.InitialDirectory = textbox.Text; // Use current value for initial dir
dialog.Title = "Select a Directory"; // instead of default "Save As"
dialog.Filter = "Directory|*.this.directory"; // Prevents displaying files
dialog.FileName = "select"; // Filename will then be "select.this.directory"
if (dialog.ShowDialog() == true) {
    string path = dialog.FileName;
    // Remove fake filename from resulting path
    path = path.Replace("\\select.this.directory", "");
    path = path.Replace(".this.directory", "");
    // If user has changed the filename, create the new directory
    if (!System.IO.Directory.Exists(path)) {
        System.IO.Directory.CreateDirectory(path);
    }
    // Our final value is in path
    textbox.Text = path;
}

このハックに関する唯一の問題は以下のとおりです。

  • 「確認」ボタンで「ディレクトリを選択」のようなものではなく「保存」と表示されますが、鉱山のような場合はディレクトリの選択を「保存」して機能します。
  • 入力フィールドにはまだ「ディレクトリ名」ではなく「ファイル名」と表示されていますが、ディレクトリはファイルの一種であると言えます...
  • 「タイプとして保存」ドロップダウンはまだありますが、その値は「ディレクトリ(* .this.directory)」と表示され、ユーザーはそれを他のものに変更することはできません。

ほとんどの人はこれらに気付かないでしょうが、マイクロソフトが彼らの評価から頭を引き出すのであれば私は間違いなく公式のWPFの方法を使うことを好むでしょう、しかし彼らがするまで、それは私の一時的な修正です。

7
Olivier St-L

ディレクトリダイアログでディレクトリパスを取得するには、まず参照System.Windows.Formsを追加し、次に解決してから、このコードをボタンクリックします。

    var dialog = new FolderBrowserDialog();
    dialog.ShowDialog();
    folderpathTB.Text = dialog.SelectedPath;

(folderpathTBは私がフォルダパスを入れたいTextBoxの名前です、OR uもそれを文字列変数に割り当てることができます)

    string folder = dialog.SelectedPath;

そして、もしあなたがFileName/pathを取得したければ、単にボタンクリックでこれをしなさい

    FileDialog fileDialog = new OpenFileDialog();
    fileDialog.ShowDialog();
    folderpathTB.Text = fileDialog.FileName;

(folderpathTBは私がファイルパスを入れたいTextBoxの名前です、OR uもそれを文字列変数に割り当てることができます)

注:[フォルダ]ダイアログの場合、System.Windows.Forms.dllをプロジェクトに追加する必要があります。そうしないと機能しません。

6
Zia Ur Rahman

OokiiフォルダダイアログはNugetにあります。

PM> Install-Package Ookii.Dialogs

そして、サンプルコードは以下の通りです。

var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
    textBoxFolderPath.Text = dialog.SelectedPath;
}
6
Youngjae

あなたが望むものを達成するための最善の方法はあなた自身のwpfベースのコントロールを作成するか、または他の人々によって作られたものを使うことです
なぜ ? wpfアプリケーションでwinformsダイアログを使用すると、パフォーマンスに著しい影響があるため(何らかの理由で)
このプロジェクトをおすすめします
https://opendialog.codeplex.com/
またはNuget:

PM> Install-Package OpenDialog

それは非常にMVVMに優しいです、そしてそれはwinformsダイアログを包みません

4
bigworld12

私はリンクの下に以下のコードを見つけました...そしてそれは働きました フォルダ選択ダイアログWPF

using Microsoft.WindowsAPICodePack.Dialogs;

var dlg = new CommonOpenFileDialog();
dlg.Title = "My Title";
dlg.IsFolderPicker = true;
dlg.InitialDirectory = currentDirectory;

dlg.AddToMostRecentlyUsedList = false;
dlg.AllowNonFileSystemItems = false;
dlg.DefaultDirectory = currentDirectory;
dlg.EnsureFileExists = true;
dlg.EnsurePathExists = true;
dlg.EnsureReadOnly = false;
dlg.EnsureValidNames = true;
dlg.Multiselect = false;
dlg.ShowPlacesList = true;

if (dlg.ShowDialog() == CommonFileDialogResult.Ok) 
{
  var folder = dlg.FileName;
  // Do something with selected folder string
}
4
Saurabh Raoot

私はナゲットパッケージに追加することをお勧めします:

  Install-Package OpenDialog

それを使用する方法は次のとおりです。

    Gat.Controls.OpenDialogView openDialog = new Gat.Controls.OpenDialogView();
    Gat.Controls.OpenDialogViewModel vm = (Gat.Controls.OpenDialogViewModel)openDialog.DataContext;
    vm.IsDirectoryChooser = true;
    vm.Show();

    WPFLabel.Text = vm.SelectedFilePath.ToString();

これがドキュメントです: http://opendialog.codeplex.com/documentation

ファイル、フィルタ付きファイル、フォルダなどに使用できます。

3
Jose Ortega

OokiiのVistaFolderBrowserDialogはあなたが望むものです。

フォルダブラウザを Ooki Dialogs からほかに何もしたくない場合 ソースをダウンロードする 、フォルダブラウザに必要なファイルを選択する(ヒント:7ファイル) .NET 4.5.2では問題なく動作します。私はSystem.Drawingへの参照を追加しなければなりませんでした。元のプロジェクトの参照をあなたのものと比較してください。

どのファイルをどのように判断しますか。アプリケーションとOokiiを異なるVisual Studioインスタンスで開きます。 VistaFolderBrowserDialog.csをアプリに追加し、ビルドエラーがなくなるまでファイルを追加し続けます。 Ookiiプロジェクトに依存関係があることがわかります - Controlキーを押しながらソースに戻るものをクリックします(意図したとおりです)。

これが怠惰すぎる場合に必要なファイルは次のとおりです。

NativeMethods.cs
SafeHandles.cs
VistaFolderBrowserDialog.cs
\ Interop
   COMGuids.cs
   ErrorHelper.cs
   ShellComInterfaces.cs
   ShellWrapperDefinitions.cs

VistaFolderBrowserDialog.csの197行目を、Resources.Resxを含めたくない限り編集します。

新しいInvalidOperationException(Properties.Resources.FolderBrowserDialogNoRootFolder)をスローします。

throw new InvalidOperationException("Unable to retrieve the root folder.");

license.txtに従って、著作権表示をアプリに追加します

\Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs行の160から169行目のコードは使用できる例ですが、WPFの場合はthis,からMessageBox.Show(this,を削除する必要があります。

私の機械で働く[TM]

2
CAD bloke

これは古い質問ですが、これを行う簡単な方法は、WPFが提供するFileDialogオプションを使用し、System.IO.Path.GetDirectory(filename)を使用することです。

2
Gregory Eaton

これらの答えのどれも私のために働きませんでした(一般的にそれらの線に沿って抜けている参照か何かがありました)

しかし、これは非常に簡単でした。

WPFアプリケーションでFolderBrowserDialogを使用

System.Windows.Formsへの参照を追加して、次のコードを使用してください。

  var dialog = new System.Windows.Forms.FolderBrowserDialog();
  System.Windows.Forms.DialogResult result = dialog.ShowDialog();

不足しているパッケージを追跡する必要はありません。あるいは巨大なクラスを追加する

これにより、新しいフォルダを作成することもできる最新のフォルダセレクタが得られます。

他のマシンにデプロイしたときの影響はまだわかりません

1
Nick.McDermaid

あなたはWPFでこのようなsmthを使うことができます。私は例のメソッドを作成しました。以下を確認してください。

public string getFolderPath()
{
           // Create OpenFileDialog 
           Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

           OpenFileDialog openFileDialog = new OpenFileDialog();
           openFileDialog.Multiselect = false;

           openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
           if (openFileDialog.ShowDialog() == true)
           {
               System.IO.FileInfo fInfo = new System.IO.FileInfo(openFileDialog.FileName);
               return fInfo.DirectoryName;
           }
           return null;           
       }
0
koberone