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
:
ShowReadOnly = true; ReadOnlyChecked = true
:
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:
A new Microsoft.Win32.Controls
namespace is introduced. The public classes and members are as follows:
New members on CommonItemDialog
:
CustomControls
OkButton
CancelButton
Remaining work:
- move exception messages to resources
- add more dialog events, e.g. filter index changed is critical for many custom controls scenarios
- check the string resources haven't moved since Vista
- debugger display attributes
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