c# 自定义文件对话框,用于根据选择添加其他控件



我想自定义一个窗口 10 样式文件对话框(打开(,在文件名下方添加附加控件(见附图(。如果可以的话,并根据选择更新附加控件。

点击这里查看图片

我怎么能做到?

- 在对话框上添加我的附加控件

- 钩子回调

我尝试像下面的代码一样钩住文件对话框,但是,似乎经典对话框仅可用。

请帮我弄清楚这一点。


public struct OpenFileName
{
public Int32 lStructSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public IntPtr lpstrFilter;
public IntPtr lpstrCustomFilter;
...
public OfnHookProc lpfnHook;
...
};
[return: MarshalAs(UnmanagedType.SysUInt)]
public delegate IntPtr OfnHookProc(IntPtr hdlg, [MarshalAs(UnmanagedType.U4)] int uiMsg, IntPtr wParam, IntPtr lParam);
public CustomizedDialog(string defaultExtension, string directoryName)
{
// Need two buffers in unmanaged memory to hold the filename
// Note: the multiplication by 2 is to allow for Unicode (16-bit) characters
_fileNameBuffer = Marshal.AllocCoTaskMem(2 * _MAX_PATH);
_fileTitleBuffer = Marshal.AllocCoTaskMem(2 * _MAX_PATH);
_directoryBuffer = Marshal.AllocCoTaskMem(2 * _MAX_PATH);
// Zero these two buffers
byte[] zeroBuffer = new byte[2 * (_MAX_PATH + 1)];
for (int i = 0; i < 2 * (_MAX_PATH + 1); i++) zeroBuffer[i] = 0;
Marshal.Copy(zeroBuffer, 0, _fileNameBuffer, 2 * _MAX_PATH);
Marshal.Copy(zeroBuffer, 0, _fileTitleBuffer, 2 * _MAX_PATH);
Marshal.Copy(zeroBuffer, 0, _directoryBuffer, 2 * _MAX_PATH);
// copy initial directory name into unmanaged memory buffer
byte[] directoryBytes = Encoding.Unicode.GetBytes(directoryName);
Marshal.Copy(directoryBytes, 0, _directoryBuffer, directoryBytes.Length);
// Populate the OPENFILENAME structure
// The flags specified are the minimal set to get the appearance and behaviour we need
_ofn.lStructSize = Marshal.SizeOf(_ofn);
_ofn.lpstrFile = _fileNameBuffer;
_ofn.nMaxFile = _MAX_PATH + 1;
_ofn.lpstrDefExt = Marshal.StringToCoTaskMemUni(defaultExtension);
_ofn.lpstrFileTitle = _fileTitleBuffer;
_ofn.nMaxFileTitle = _MAX_PATH + 1;
_ofn.lpstrInitialDir = _directoryBuffer;
_ofn.lpstrFilter = Marshal.StringToCoTaskMemUni(String.Format(CultureInfo.InvariantCulture, "txt *.txt"));
string title = String.Format(CultureInfo.InvariantCulture, "title");
_ofn.lpstrTitle = Marshal.StringToCoTaskMemUni(title);
_ofn.lpfnHook = new OfnHookProc(MyHookProc);
}
public bool Show()
{
User32.GetOpenFileName(ref _ofn);
return true;
}
public IntPtr MyHookProc(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)] int msg, IntPtr wParam, IntPtr lParam)
{
...
}

我自己找到了解决方案。 请尝试在Windows7APICodePack中使用CommonOpenFileDialog或CommonSaveFileDialog。https://www.nuget.org/packages/Windows7APICodePack-Shell/

  • https://social.msdn.microsoft.com/Forums/sqlserver/en-US/3b55d433-b1e3-4943-ba28-69c72b613c91/get-folder-name-from-browserdialog-in-wpf-c?forum=wpf

  • https://github.com/Corillian/Windows-API-Code-Pack-1.1

使用软件包实现真的很容易。 下面是添加控件的示例。

public static CommonOpenFileDialog OpenFileDialog(string title, List<CommonFileDialogFilter> filters, string initialDirectory = "", bool multiselect = false)
{
var openFilerDialog = new CommonOpenFileDialog();
openFilerDialog.EnsureReadOnly = true;
openFilerDialog.IsFolderPicker = false;
openFilerDialog.AllowNonFileSystemItems = false;
openFilerDialog.Multiselect = multiselect;
openFilerDialog.Title = title;
if (filters != null)
{
foreach (var filter in filters)
{
openFilerDialog.Filters.Add(filter);
}
}
if (!string.IsNullOrEmpty(initialDirectory))
{
openFilerDialog.InitialDirectory = initialDirectory; // Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
}
return openFilerDialog;
}
private void CustomOpenFileDialog_Click(object sender, RoutedEventArgs e)
{
var dialog = FileDialog.OpenFileDialog("Custom OpenFileDialog", new List<CommonFileDialogFilter>() { new CommonFileDialogFilter("stl", "*.stl") });
AddOpenFileDialogCustomControls(dialog);
var dialogResult = dialog.ShowDialog();
}
public static void AddOpenFileDialogCustomControls(CommonFileDialog openDialog)
{
// Add a RadioButtonList
CommonFileDialogRadioButtonList list = new CommonFileDialogRadioButtonList("radioButtonOptions");
list.Items.Add(new CommonFileDialogRadioButtonListItem("Option A"));
list.Items.Add(new CommonFileDialogRadioButtonListItem("Option B"));
list.SelectedIndex = 1;
openDialog.Controls.Add(list);
}

最新更新