OpenFolderDialog by miloush · Pull Request #7244 · dotnet/wpf (original) (raw)
Fixes #438. Further discussion in #4039. Previous attempt: #6351
This PR contains runtime breaking changes. For minimal implementation of #438 without breaking changes see #6374. EDIT: Introducing a base class is not breaking.
Description
Allows developers to ask the user to select a folder, a feature known as FolderBrowserDialog
in WinForms. This PR
- removes all legacy (Windows XP) dialogs
- splits the existing inheritance and moves common members up the hierarchy, so that members only available or working for files are not present for the folder browsing.
Note that this abstraction does not exist in the native code, there is only a flag to pick folders on FileOpenDialog (akin to #6374).
What used to be FileDialog.Options
is now strictly for the native API usage, so there is no longer need to mix and mask them.
Example usage
OpenFolderDialog dialog = new OpenFolderDialog(); dialog.Multiselect = true; dialog.ShowDialog(); string[] folders = dialog.FileNames;
Compatibility requirements and limitations
The goal for this PR was to preserve compile-time compatibility, but not run-time compatibility. Old PresentationFramework.dll assembly cannot be replaced by a new one, the application using it has to be recompiled (since members moved around types).
Anything that compiled before should still compile without changes. Most notably, while developers cannot derive from FileDialog
due to internal abstract members, deriving from CommonDialog
is possible. If this scenario was not required to be supported, I would further remove the following members as part of removing support for legacy dialogs:
protected CommonDialog.HookProc
private CommonDialog.MoveToScreenCenter
Not that inserting a class before FileDialog
is the only place where class can be inserted if compatibility with .NET Framework API is to be preserved. If that was not a requirement, it would be possible to insert a class after FileDialog
, which would be a bit more natural. Finally, if .NET Framework API surface was not a requirement AND we would be happy polluting the base class of possible inheritors of CommonDialog
, we could treat CommonDialog
newly as for IFileDialog
API only and not insert any new classes in the hierarchy.
.NET Framework baseline contains changes to FileDialog
that would be breaking if developers could inherit from the dialog, but as noted above, that is not allowed.
Naming considerations
- CommonItemDialog is a name coming from the documentation. The native dialog works with any
IShellItem
s, not only file-based ones. I envision in the future if the code was extended to support arbitrary shell items,CommonItemDialog
could provide the selection as shell itemsand the derived classes would utilize those for. EDIT:FileNames
resp.FolderNames
instead of doing their own conversionFileNames
were now lifted up toCommonItemDialog
, shared for both files and folders. - OpenFolderDialog is for parity with
OpenFileDialog
. Note that the save dialog no longer supports folder selection, so there is no need for an extra emptyFolderDialog
class in-between. - FileName(s) makes the design much simpler (than having separate FolderNames) and reflects the native API. Note also that when dereferencing is disabled, results may contain shortcut files pointing to folders.
Customer Impact
Without this fix, users have to either use WinForms' FolderBrowserDialog
, resort to 3rd party libraries or re-implement the whole IFileDialog
API. #438 is currently the top voted issue in the repository.
Regression
No.
Known issues in the already existing code that are not addressed by this PR:
- read-only check box not available OpenFileDialog.ShowReadOnly does not work #6346
ValidateNames
is used to do several unrelated things - alleged invalid filename checking (that does not seem to be happening or necessary); processing file names, adding extensions, showing prompts etc.; and as a flag to native API to try create a dummy file to ensure user has rights to access the selected path.AddExtension
works differently from the native API extension enforcements, so it is not realized as an API flag in the PRCreatePrompt
andOverwritePrompt
are also implemented differently than the nativeFOS_CREATEPROMPT
resp.FOS_OVERWRITEPROMPT
, notably create prompt only works for open dialogs, not save dialogs where it is defined in the WPF API, so they are not realized as API flags in the PR
Testing
Compiled and manually tested on 7.0.0-rc.2.22472.3. Ensured overwrite and create prompts did not regress, cancelling the dialog did not regress restoring file names and filter index.
Risk
Medium risk - No public API removed, a new base class introduced. Current applications using the types will keep working without recompilation. Code using reflection even on public types might break if it is not flattening them.
Applications with Windows XP compatibility flag when recompiled will still work, however, the dialogs will use the IFileDialog
API rather than the legacy dialogs.
/cc @Symbai @ThomasGoulet73 @fabiant3 @batzen @lindexi