File dialog controls by miloush · Pull Request #7256 · dotnet/wpf (original) (raw)

Fixes #6346

Note: This PR is based on #7244. For review, see the individual commits, most notably 2e7aab3 and 74d617c. I can rebase if #7244 was not going in.

Description

Legacy (Windows XP) file dialog had a flag for showing a read-only checkbox, controlled by OpenFileDialog.ShowReadOnly. The IFileDialog API used since Vista does not have such flag, but the code has not been updated. As a result, ShowReadOnly and ReadOnlyChecked properties do not work.

This PR fixes the issue by matching the IFileDialog API fallback for legacy applications, i.e. by adding dropdown items to the OK button:

ShowReadOnly = true; ReadOnlyChecked = false:
image

ShowReadOnly = true; ReadOnlyChecked = true:
image

The strings come from comdlg32.dll resources and will be in the language of the OS.

Implementation

In order to support the drop-down items on the OK button, IFileDialogCustomize and IFileDialogControlEvents were implemented (together with IFileDialog2 for customizing the Cancel button). Controls can be added to all of OpenFileDialog, SaveFileDialog and OpenFolderDialog.

For example,

var dialog = new SaveFileDialog(); dialog.Filter = "All files (.)|.";

var radioGroup = new FileDialogVisualGroup("RadioButtonList"); radioGroup.Add(new FileDialogRadioButtonList("_radio 1", "r_adio 2", "ra_dio 3")); dialog.CustomControls.Add(radioGroup);

var checkGroup = new FileDialogVisualGroup("CheckButtons"); checkGroup.Add(new FileDialogCheckButton("_check 1")); checkGroup.Add(new FileDialogCheckButton("c_heck 2", false)); checkGroup.Add(new FileDialogCheckButton("chec_k 3", true)); dialog.CustomControls.Add(checkGroup);

var menuGroup = new FileDialogVisualGroup("Menus and separator"); menuGroup.Add(new FileDialogMenu("_menu 1", "item _1", "item _2")); menuGroup.Add(new FileDialogSeparator()); menuGroup.Add(new FileDialogMenu("m_enu 2", "item")); dialog.CustomControls.Add(menuGroup);

var comboGroup = new FileDialogVisualGroup("ComboBoxes"); comboGroup.Add(new FileDialogComboBox("item _1", "item &2", "item 3")); comboGroup.Add(new FileDialogComboBox("item _1", "item &2", "item 3") { SelectedIndex = 1 }); dialog.CustomControls.Add(comboGroup);

var textGroup = new FileDialogVisualGroup("Text and EditBo_x"); textGroup.Add(new FileDialogText("Generic _label")); textGroup.Add(new FileDialogEditBox("a text box 😊")); dialog.CustomControls.Add(textGroup);

var pushButton = new FileDialogPushButton("A button not in a _group"); pushButton.Click += delegate { MessageBox.Show("Clicked!"); }; dialog.CustomControls.Add(pushButton);

var prominentGroup = new FileDialogVisualGroup("Pro_minent control", new FileDialogComboBox()); dialog.CustomControls.Add(prominentGroup); dialog.CustomControls.Prominent = prominentGroup;

dialog.OkButton.Items.Add("_Add"); dialog.OkButton.Items.Add("Add a_ll"); dialog.CancelButton.CustomLabel = "_Done";

dialog.ShowDialog();

gives:

image

A new Microsoft.Win32.Controls namespace is introduced. The public classes and members are as follows:

CustomControls

New members on CommonItemDialog:

Remaining work:

Customer Impact

Not taking this fix leaves the read-only properties broken.

Furthermore, customers must rely on alternative solutions for file dialog controls. Many applications, from Notepad to Office to Visual Studio, use custom controls in their file dialogs.

Regression

No.

Testing

Manual testing using 7.0.100-rc.2.22477.23. Ensured ReadOnlyChecked is respected when dialog is shown and reflects the correct value when dialog is confirmed.

Ensured all controls render, their state can be read after dialog is confirmed and is reverted when the dialog is cancelled. Limited testing of dynamically adding and removing items and changing controls' labels, visibility and status while the dialog is shown.

Risk

Medium. While the existing code already heavily depends on comdlg32.dll, this fix introduces an extra dependency on 3 of its resource strings. Alternatively these strings could be separately localized as part of WPF, but that might result in an inconsistencies since the language coverage of OS and WPF localization differs.

Furthermore, the controls introduce a possibility for the dialogs to be easily manipulated while they are being shown, which has not been possible before. While the existing properties are mostly read when the dialog is shown and updated when it is closed, a review should be done on whether they could and should be "live".

/cc @KirillOsenkov

Microsoft Reviewers: Open in CodeFlow