web-dev-qa-db-ja.com

SaveFileDialogの初期ディレクトリを設定しますか?

次の動作のSaveFileDialogが欲しい:

  • 初めて開くと、「マイドキュメント」に移動します。

  • その後、最後に選択したフォルダーに移動します。これを達成する最良の方法は何ですか?

InitialDirectoryを設定しない場合、exeのディレクトリに移動します-これは私が望んでいるものではありません。ただし、実行間であっても、最後に選択したディレクトリが記憶されます。

InitialDirectoryを設定すると、最後に選択したディレクトリが記憶されません。もちろん、最後に選択したディレクトリをレジストリに保存することもできます:(しかし、より良い解決策を探しています。

      SaveFileDialog dialog = new SaveFileDialog();
      //??? dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
      dialog.ShowDialog();

何かアドバイス?

36
tom greene

RestoreDirectory プロパティと trueInitialDirectoryに設定する必要があります。

33
Andrew Hare

なぜこれが機能するのかわかりませんが、ようやく機能するようになりました。

完全なパスを指定した場合は機能しませんが、その完全なパスを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;
15
Jeffrey Harmon

[初期ディレクトリ]プロパティを設定する前に、ディレクトリパスが存在することを確認してください。ディレクトリが存在しない場合は作成します。すなわち

if (!Directory.Exists(FooDirectory))
{
     Directory.CreateDirectory(FooDirectory);
}
4
user1956901

私もさまざまな場所で見つかったさまざまな「解決策」を試しましたが、レジストリにMRUリストエントリがあるとすぐに機能しないようです:/しかし、ここに私の簡単な回避策があります…

ダイアログのInitialDirectoryプロパティを設定する代わりに、FileNameプロパティをパスに設定しますが、選択したFilterと組み合わせます。例:

dialog.FileName = Path.Combine(myPath, "*.*");
3
mousio

推奨される回避策は私にとってはうまくいきませんでしたので、 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を使用します。ダイアログが使用されると、以前のディレクトリを記憶するデフォルトの動作に戻ります。

1
danio

InitialDirectorynullに設定すると、最初にユーザー履歴を回避できることがわかりました。

    OpenFileDialog dlgOpen = new OpenFileDialog();
    dlgOpen.InitialDirectory = null;
    dlgOpen.InitialDirectory = @"c:\user\MyPath";
1
user104933

提供されたソリューションはどれも悲しいことに私には役に立たなかった。

OP仕様に加えて、プログラムが実行間の最後の保存場所を記憶することを望みました。そのためには、Visual StudioのソリューションエクスプローラーのProjectName -> Properties -> Settings.settings、次のプロパティを設定します。

Settings.settings property: Name=PreviousPath, Type=string, Scope=User, leave Value empty

プログラムの実行中は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...
}

これは動作を与えます:

  • プログラムを初めて実行してダイアログを開くと、「マイドキュメント」に移動します。
  • 連続して実行され、ダイアログが開きました:
    • 以前に開いたときに保存した場合、以前の保存場所に移動します。
    • 以前に開いたときに保存されていない場合は、「マイドキュメント」に移動します。
1
OhBeWise

私も正確な問題を抱えていたので、この議論を検討したかったのです(数年遅すぎました)。 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;
}

これは私にとって望ましい振る舞いを提供しますが、もっとエレガントなソリューションがあればよかったと思います。

0
savefiledialog.InitialDirectory = Application.StartupPath;
savefiledialog.RestoreDirectory = true;

少し前にテストしました。

0
PauLEffect

パスのどこかでスラッシュを使用すると、InitialDirectoryは機能しません。それらがバックスラッシュに変換されていることを確認してください

0
Ali Akbar

「出力ファイルを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)
0
Andrew Mills

これが私が最終的に得たものであり、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();
    }
}
0
vapcguy

.NET 2.0でいくつかのテストを行いましたが、FileNameをリテラル文字列以外に設定すると動作しないようです。メソッドまたはアクセッサを使用してプロパティを設定すると、初期ディレクトリは無視されます。

0
Icono123