次に生成するファイルを保存するディレクトリをユーザーに選択させてください。私はWPFで私はWin32からのOpenFileDialog
を使うべきであることを知っています、しかし残念なことにダイアログはファイルを選択することを要求します - 選択せずに単にOKをクリックするならそれは開いたままです。ユーザーにファイルを選択させ、それからパスを取り除いてそれがどのディレクトリに属しているのかを判断させることで、機能を「ハックアップ」することができますが、それはせいぜい直感的ではありません。誰かがこれを以前にやったのを見たことがありますか?
これには組み込みの 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ダイアログを使うことを可能にするいくつかの選択肢があります。 :
using Microsoft.WindowsAPICodePack.Dialogs;
...
var dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();
このダイアログは、Windows Vistaより古いオペレーティングシステムでは利用できないので、必ず最初にCommonFileDialog.IsPlatformSupported
を確認してください。
私はこのように使用される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();
}
}
}
}
私は Ookii dialogs をしばらく使っていますが、WPFにはうまく働きます。
これがダイレクトページです。
カスタムダイアログを作成したくないが、それでも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;
}
このハックに関する唯一の問題は以下のとおりです。
ほとんどの人はこれらに気付かないでしょうが、マイクロソフトが彼らの評価から頭を引き出すのであれば私は間違いなく公式のWPFの方法を使うことを好むでしょう、しかし彼らがするまで、それは私の一時的な修正です。
ディレクトリダイアログでディレクトリパスを取得するには、まず参照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をプロジェクトに追加する必要があります。そうしないと機能しません。
OokiiフォルダダイアログはNugetにあります。
PM> Install-Package Ookii.Dialogs
そして、サンプルコードは以下の通りです。
var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
textBoxFolderPath.Text = dialog.SelectedPath;
}
あなたが望むものを達成するための最善の方法はあなた自身のwpfベースのコントロールを作成するか、または他の人々によって作られたものを使うことです
なぜ ? wpfアプリケーションでwinformsダイアログを使用すると、パフォーマンスに著しい影響があるため(何らかの理由で)
このプロジェクトをおすすめします
https://opendialog.codeplex.com/
またはNuget:
PM> Install-Package OpenDialog
それは非常にMVVMに優しいです、そしてそれはwinformsダイアログを包みません
私はリンクの下に以下のコードを見つけました...そしてそれは働きました フォルダ選択ダイアログ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
}
私はナゲットパッケージに追加することをお勧めします:
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
ファイル、フィルタ付きファイル、フォルダなどに使用できます。
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]
これは古い質問ですが、これを行う簡単な方法は、WPFが提供するFileDialogオプションを使用し、System.IO.Path.GetDirectory(filename)を使用することです。
これらの答えのどれも私のために働きませんでした(一般的にそれらの線に沿って抜けている参照か何かがありました)
しかし、これは非常に簡単でした。
WPFアプリケーションでFolderBrowserDialogを使用
System.Windows.Forms
への参照を追加して、次のコードを使用してください。
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
不足しているパッケージを追跡する必要はありません。あるいは巨大なクラスを追加する
これにより、新しいフォルダを作成することもできる最新のフォルダセレクタが得られます。
他のマシンにデプロイしたときの影響はまだわかりません
あなたは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;
}