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 \0*.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)
{
    ...
}

1 ответ

Решение

Я нашел решение сам. Пожалуйста, попробуйте использовать CommonOpenFileDialog или CommonSaveFileDialog в Windows7APICodePack. https://www.nuget.org/packages/Windows7APICodePack-Shell/

относится

Это действительно легко реализовать с помощью пакета. Вот пример для добавления элементов управления.

    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);
    }
Другие вопросы по тегам