次の動作のSaveFileDialogが欲しい:
初めて開くと、「マイドキュメント」に移動します。
その後、最後に選択したフォルダーに移動します。これを達成する最良の方法は何ですか?
InitialDirectoryを設定しない場合、exeのディレクトリに移動します-これは私が望んでいるものではありません。ただし、実行間であっても、最後に選択したディレクトリが記憶されます。
InitialDirectoryを設定すると、最後に選択したディレクトリが記憶されません。もちろん、最後に選択したディレクトリをレジストリに保存することもできます:(しかし、より良い解決策を探しています。
SaveFileDialog dialog = new SaveFileDialog();
//??? dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
dialog.ShowDialog();
何かアドバイス?
RestoreDirectory
プロパティと true
をInitialDirectory
に設定する必要があります。
なぜこれが機能するのかわかりませんが、ようやく機能するようになりました。
完全なパスを指定した場合は機能しませんが、その完全なパスをPath.GetFullPath()内に配置すると機能します。前と後の値を見ると、それらが同じであることがわかりますが、それなしでは一貫して機能せず、動作します。
//does not work
OpenFileDialog dlgOpen = new OpenFileDialog();
string initPath = Path.GetTempPath() + @"\FQUL";
dlgOpen.InitialDirectory = initPath;
dlgOpen.RestoreDirectory = true;
//works
OpenFileDialog dlgOpen = new OpenFileDialog();
string initPath = Path.GetTempPath() + @"\FQUL";
dlgOpen.InitialDirectory = Path.GetFullPath(initPath);
dlgOpen.RestoreDirectory = true;
[初期ディレクトリ]プロパティを設定する前に、ディレクトリパスが存在することを確認してください。ディレクトリが存在しない場合は作成します。すなわち
if (!Directory.Exists(FooDirectory))
{
Directory.CreateDirectory(FooDirectory);
}
私もさまざまな場所で見つかったさまざまな「解決策」を試しましたが、レジストリにMRUリストエントリがあるとすぐに機能しないようです:/しかし、ここに私の簡単な回避策があります…
ダイアログのInitialDirectory
プロパティを設定する代わりに、FileName
プロパティをパスに設定しますが、選択したFilter
と組み合わせます。例:
dialog.FileName = Path.Combine(myPath, "*.*");
推奨される回避策は私にとってはうまくいきませんでしたので、 WPF OpenFileDialogは最後に開いたファイルのディレクトリをどのように追跡しますか? 私は実装しました:
public static void SetInitialDirectory(this FileDialog dlg, string fileExtension, string initialDirectory)
{
// RestoreDirectory doesn't seem to be implemented - https://stackoverflow.com/questions/11144770/how-does-wpf-openfiledialog-track-directory-of-last-opened-file
// so manually only set InitialDirectory if nothing is stored
try
{
var mru = @"Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU\" + fileExtension;
var rk = Registry.CurrentUser.OpenSubKey(mru);
if (rk == null)
{
dlg.InitialDirectory = initialDirectory;
}
}
catch (Exception)
{
// SecurityException, ObjectDisposedException => allow default behaviour
}
}
このファイル拡張子に対してダイアログが以前に使用されていない場合、これは提供されたinitialDirectoryを使用します。ダイアログが使用されると、以前のディレクトリを記憶するデフォルトの動作に戻ります。
InitialDirectory
をnull
に設定すると、最初にユーザー履歴を回避できることがわかりました。
OpenFileDialog dlgOpen = new OpenFileDialog();
dlgOpen.InitialDirectory = null;
dlgOpen.InitialDirectory = @"c:\user\MyPath";
提供されたソリューションはどれも悲しいことに私には役に立たなかった。
OP仕様に加えて、プログラムが実行間の最後の保存場所を記憶することを望みました。そのためには、Visual StudioのソリューションエクスプローラーのProjectName -> Properties -> Settings.settings
、次のプロパティを設定します。
プログラムの実行中はSaveFileDialog
を保持しているので、開始時にインスタンス化します。次に、ダイアログを表示するためのCommand
で:
if (string.IsNullOrEmpty(Settings.Default.PreviousPath))
{
this.saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
}
else
{
this.saveDialog.InitialDirectory = Settings.Default.PreviousPath;
}
this.saveDialog.FileName = "Default_File_Name";
bool result = this.saveDialog.ShowDialog() ?? false;
if (result)
{
Settings.Default.PreviousPath = Path.GetDirectoryName(this.saveDialog.FileName);
Settings.Default.Save();
// Code writing to the new file...
}
これは動作を与えます:
私も正確な問題を抱えていたので、この議論を検討したかったのです(数年遅すぎました)。 openFileDialogのプロパティと関数を使用することで、この動作(つまり、最初にデフォルトパスを使用し、その後、以前に選択したパスを使用する)を達成できると信じられるようになったとしても、(今では)単純に不可能です!
作業ディレクトリを目的のデフォルトパス(たとえばEnvironment.CurrentDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
)に変更することもできますが、Unityなどの一部のフレームワークはこれをあまり気にせずに終了します。
このため、私はこのコードで終わりました:
private bool firstDialogOpened = true;
public void BrowseFiles()
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Model files (*.obj)|*.obj|All files (*.*)|*.*";
openFileDialog.FilterIndex = 1;
if (firstDialogOpened)
{
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
firstDialogOpened = false;
}
if (openFileDialog.ShowDialog() == DialogResult.OK)
filepath.text = openFileDialog.FileName;
}
これは私にとって望ましい振る舞いを提供しますが、もっとエレガントなソリューションがあればよかったと思います。
savefiledialog.InitialDirectory = Application.StartupPath;
savefiledialog.RestoreDirectory = true;
少し前にテストしました。
パスのどこかでスラッシュを使用すると、InitialDirectoryは機能しません。それらがバックスラッシュに変換されていることを確認してください
「出力ファイルをvb.netの目的のディレクトリに保存するという点では、次のように機能していることがわかりました。
Dim filcsv As String = fileNamey.Replace(".txt", "_Denied2.csv")
Dim filcsv2 As String = fileNamey.Replace(".txt", "_Approved2.csv")
Dim outputDirectory As String = "C:\Users\jlcmil\Documents\EnableMN\output\"
Dim totalPath As String = System.IO.Path.Combine(outputDirectory, filcsv)
Dim totalPath2 As String = System.IO.Path.Combine(outputDirectory, filcsv2)
Dim outDenied As StreamWriter = New StreamWriter(totalPath)
Dim outApproved As StreamWriter = New StreamWriter(totalPath2)
これが私が最終的に得たものであり、OPがダイアログをポイントしたい場所に沿っています。
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.InitialDirectory = null;
// May or may not want "saves", but this shows how to append subdirectories
string path = (Path.Combine(Environment.ExpandEnvironmentVariables("%USERPROFILE%"), "My Documents") + "\\saves\\");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
dlg.InitialDirectory = path;
dlg.RestoreDirectory = true;
if (dlg.ShowDialog().Value == true)
{
// This is so you can have JUST the directory they selected
path = dlg.FileName.Remove(dlg.FileName.LastIndexOf('\\'), dlg.FileName.Length - dlg.FileName.LastIndexOf('\\'));
string filePath = Path.Combine(path, fileName);
// This is "just-in-case" - say they created a new directory in the dialog,
// but the dialog doesn't seem to think it exists because it didn't see it on-launch?
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
// Remove a file if it has the same name
if (File.Exist(filePath))
File.Delete(filePath);
// Write the file, assuming you have and pass in the bytes
using (FileStream fs = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write)
{
fs.Write(bytes, 0, (int)bytes.Length);
fs.Close();
}
}
.NET 2.0でいくつかのテストを行いましたが、FileNameをリテラル文字列以外に設定すると動作しないようです。メソッドまたはアクセッサを使用してプロパティを設定すると、初期ディレクトリは無視されます。