SaveFileDialog 在类型更改时导航到文件夹
SaveFileDialog Navigate to Folder on Type Change
我正在尝试复制 Microsoft Word 中“保存文件”对话框的某些行为。在 Word(Office 365 最新版本)中,如果您转到“另存为”并打开浏览对话框,默认目录是“我的文档”,如果您随后将“另存为”类型更改为 "Word Template (*.dotx)",这会自动将您带到 "Custom Office Templates" 文件夹。这是我想要复制的行为。
据我所知,这在使用 Microsoft.Win32.SaveFileDialog 的 WPF 中是不可能的,如有不妥请指正。
所以我尝试使用 Microsoft.WindowsAPICodePack.Shell Nuget 包中的 CommonSaveFileDialog。我相信我已经很接近了,但我似乎无法在更改类型时让它真正执行导航部分。请参阅下面的代码,非常感谢任何建议。我需要这个用于 WPF 桌面应用程序。
CommonSaveFileDialog saveDialog;
private void Button_Click(object sender, RoutedEventArgs e)
{
saveDialog = new CommonSaveFileDialog();
saveDialog.Filters.Add(new CommonFileDialogFilter("My File", ".mf"));
saveDialog.Filters.Add(new CommonFileDialogFilter("My Template File", ".mft"));
saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
saveDialog.FileTypeChanged += saveDialog_FileTypeChanged;
saveDialog.ShowDialog();
}
private void saveDialog_FileTypeChanged(object sender, EventArgs e)
{
var selectedSaveAsType = saveDialog.Filters[saveDialog.SelectedFileTypeIndex - 1];
if (selectedSaveAsType.DisplayName == "My Template File (*.mft)")
{
//These don't cause a navigation... How can I achieve this?
//saveDialog.InitialDirectory = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "My Application Templates");
//saveDialog.DefaultDirectory = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "My Application Templates");
}
else
{
//saveDialog.DefaultDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
}
}
如果您需要任何进一步的信息,请告诉我。预先感谢您的任何建议。 :)
似乎没有任何 .CurrentDirectory 或 .Path 属性。或者任何类型的导航方法。
似乎 CommonSaveFileDialog
没有公开任何让您设置当前目录的属性 - 至少我找不到。
如果你真的想这样做,你可能需要深入挖掘。 CommonSaveFileDialog
在内部使用原生 Common Dialog Box Library。 可能 有一种方法可以让你在那个级别上做你想做的事,你必须仔细阅读文档。如果是这样,您可以直接调用它 p/invoke 样式。
搜索某种排序方法/属性 使用 .GetType().GetMethods() 更改文件夹后,仍然没有任何结果。所以我使用 dnSpy 反编译了 DLL,这导致我在 IFileDialog 中找到了一个 SetFolder 方法。
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
我实现目标的唯一方法是克隆 Nuget 包的 GitHub 存储库并自己添加到其中。我将以下 public 方法添加到 CommonFileDialog class.
public void SetFolder(string folderPath)
{
// Create a native shellitem from our path
// Add some proper error handling to ensure directory exists....
Guid guid = new Guid(ShellIIDGuid.IShellItem2);
IShellItem2 defaultDirectoryShellItem;
ShellNativeMethods.SHCreateItemFromParsingName(folderPath, IntPtr.Zero, ref guid, out defaultDirectoryShellItem);
nativeDialog.SetFolder(defaultDirectoryShellItem);
}
然后我只需调用
就可以在我的应用程序中使用它
dialog.SetFolder(@"C:\");
我正在尝试复制 Microsoft Word 中“保存文件”对话框的某些行为。在 Word(Office 365 最新版本)中,如果您转到“另存为”并打开浏览对话框,默认目录是“我的文档”,如果您随后将“另存为”类型更改为 "Word Template (*.dotx)",这会自动将您带到 "Custom Office Templates" 文件夹。这是我想要复制的行为。
据我所知,这在使用 Microsoft.Win32.SaveFileDialog 的 WPF 中是不可能的,如有不妥请指正。
所以我尝试使用 Microsoft.WindowsAPICodePack.Shell Nuget 包中的 CommonSaveFileDialog。我相信我已经很接近了,但我似乎无法在更改类型时让它真正执行导航部分。请参阅下面的代码,非常感谢任何建议。我需要这个用于 WPF 桌面应用程序。
CommonSaveFileDialog saveDialog;
private void Button_Click(object sender, RoutedEventArgs e)
{
saveDialog = new CommonSaveFileDialog();
saveDialog.Filters.Add(new CommonFileDialogFilter("My File", ".mf"));
saveDialog.Filters.Add(new CommonFileDialogFilter("My Template File", ".mft"));
saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
saveDialog.FileTypeChanged += saveDialog_FileTypeChanged;
saveDialog.ShowDialog();
}
private void saveDialog_FileTypeChanged(object sender, EventArgs e)
{
var selectedSaveAsType = saveDialog.Filters[saveDialog.SelectedFileTypeIndex - 1];
if (selectedSaveAsType.DisplayName == "My Template File (*.mft)")
{
//These don't cause a navigation... How can I achieve this?
//saveDialog.InitialDirectory = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "My Application Templates");
//saveDialog.DefaultDirectory = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "My Application Templates");
}
else
{
//saveDialog.DefaultDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
}
}
如果您需要任何进一步的信息,请告诉我。预先感谢您的任何建议。 :)
似乎没有任何 .CurrentDirectory 或 .Path 属性。或者任何类型的导航方法。
似乎 CommonSaveFileDialog
没有公开任何让您设置当前目录的属性 - 至少我找不到。
如果你真的想这样做,你可能需要深入挖掘。 CommonSaveFileDialog
在内部使用原生 Common Dialog Box Library。 可能 有一种方法可以让你在那个级别上做你想做的事,你必须仔细阅读文档。如果是这样,您可以直接调用它 p/invoke 样式。
搜索某种排序方法/属性 使用 .GetType().GetMethods() 更改文件夹后,仍然没有任何结果。所以我使用 dnSpy 反编译了 DLL,这导致我在 IFileDialog 中找到了一个 SetFolder 方法。
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
我实现目标的唯一方法是克隆 Nuget 包的 GitHub 存储库并自己添加到其中。我将以下 public 方法添加到 CommonFileDialog class.
public void SetFolder(string folderPath)
{
// Create a native shellitem from our path
// Add some proper error handling to ensure directory exists....
Guid guid = new Guid(ShellIIDGuid.IShellItem2);
IShellItem2 defaultDirectoryShellItem;
ShellNativeMethods.SHCreateItemFromParsingName(folderPath, IntPtr.Zero, ref guid, out defaultDirectoryShellItem);
nativeDialog.SetFolder(defaultDirectoryShellItem);
}
然后我只需调用
就可以在我的应用程序中使用它dialog.SetFolder(@"C:\");