-
Notifications
You must be signed in to change notification settings - Fork 1.2k
PickFolders option for OpenFileDialog #6351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Although this is probably not getting merged within the next 2 years, I'm okay with it. Thanks for your work and taking over the PR. Hopefully you'll have a stronger endurance on receiving repo owner's feedback, it could take a great while... |
src/Microsoft.DotNet.Wpf/src/PresentationFramework/Microsoft/Win32/OpenFileDialog.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.DotNet.Wpf/src/PresentationFramework/Microsoft/Win32/FileDialog.cs
Outdated
Show resolved
Hide resolved
|
May i ask why we even care about non Vista OS? Is any OS version pre Vista still supported by .NET 7? |
|
@batzen I had two reasons:
|
|
Also note that couple of the members are |
|
OK I addressed @ThomasGoulet73 feedback but I am no longer happy with the PR. It is failing at being transparent & minimal, without taking advantage of more substantial changes. I will do two new ones, one simple without splitting options and one with breaking changes. |
For discussion. Fixes #438. Further discussion in #4039.
Description
Allows developers to ask the user to select a folder, a feature known as
FolderBrowserDialogin WinForms.This PR is the least invasive way of introducing the feature. It closely reflects the underlying API design, i.e. the ability to specify
FOS_PICKFOLDERSon theIOpenFileDialog. This is a backwards compatible solution - no public API has been moved or removed and no existing behavior has changed.Tracking the flags
There is, however, an unfortunate implementation detail - the original authors of the code decided to use a single variable to store legacy OFN_ options, Vista FOS_ options and their own custom options. These options diverged and conflict with each other:
* allowed to set in code as flags (i.e. preserved by masking)
Most notably
FOS_PICKFOLDERSconflicts withOFN_ENABLEHOOK. The existing code sort of supports only the flags having the same value in both API and passes the combination directly to the APIs. Few conflicting ones are enforced at call time and developers cannot disable them:For legacy dialogs, that is:
OFN_EXPLOREROFN_ENABLEHOOKOFN_ENABLESIZINGFor Vista dialogs, that is:
FOS_DEFAULTNOMINIMODEFOS_FORCEFILESYSTEMUsing the existing infrastructure would mean either
OFN_EXPLORERbit to also meanFOS_PICKFOLDERS, or;OPTION_PICKFOLDERS, preferably as one of the unoccupied bits.The former is messy (either requires casting from FOS or declaring fake OFN constant) and creates confusing code. The latter is in danger that new conflicting flags will be introduced, like it already happened with
OPTION_ADDEXTENSION.I therefore decided for a potentially controversial solution - I split the backing field and track legacy and Vista options separately. The custom option stays in the legacy field, as no new flags are expected in the legacy API. I am willing to implement options 1) or 2) instead if that was preferred.
New visible members
In
OpenFileDialog:public bool PickFolders { get; set; }In
FileDialog:protected int VistaOptions { get; }CheckFileExists behavior
The
OpenFileDialogturns onCheckFileExistsby default. The property works as advertised, meaning users cannot confirm anything if only folders are available to pick. For convenience, setting thePickFoldersoption has a side effect of unsetting theCheckFileExistsoption.Existing properties on folder dialog
(excerpt from discussion in #4039)
These are the current public properties on the
FileDialog.Applicable to folder selection:
CustomPlacesDereferenceLinks- whether links to folders are followed or not allowedFileName- e.g. C:\Users\ThomasFileNames- always has 1 item at the momentInitialDirectorySafeFileName- e.g. ThomasSafeFileNames- always has 1 item at the momentTagTitleDoing something, but wouldn't be necessary for folders:
AddExtension- internal WPF flag to ensure the file/folder name ends with an extensionCheckFileExists- makes it unable to select a folder, see aboveDefaultExt- the extension to add by defaultValidateNames- this one is a red flag, the WPF documentation says "indicating whether the dialog box accepts only valid Win32 file names." which is how theOFN_NOVALIDATEflag works in the legacy file dialogs. However, for the Vista dialogs, theFOS_NOVALIDATEflag means "check for situations that would prevent an application from opening the selected file, such as sharing violations or access denied errors."). In addition to the dialog behavior, WPF uses the flag for adding extensions and prompting for overwriting existing files.Note that
DefaultExtwithAddExtensionsare already available for open file dialog which doesn't make much sense, but they work the same when folders are selected.Valid but currently without any effect:
CheckPathExists- only existing folders are available for selection currentlyRestoreDirectory- applicable to legacy dialogs only, not used in Vista dialogsInvalid (the native call returns an error):
FilterFilterIndexExisting methods on folder dialog
OpenFileandOpenFilesthrowUnauthorisedAccessExceptionon folders. The existing code should already expect this type of exception when opening files.Legacy behavior
The code currently throws
PlatformNotSupportedexception on Windows XP. If that is acceptable, exception message needs to be added. If not, support forSHBrowseForFolderAPI needs to be implemented, which carries non-trivial number of native types (or WinForms version called instead).Customer Impact
Without this fix, users have to either use WinForms'
FolderBrowserDialog, resort to 3rd party libraries or re-implement the wholeIFileDialogAPI. #438 is currently the top voted issue in the repository.Regression
No.
Testing
Compiled custom PresentationFramework.dll and tested in 6.0.2 x86 app that both folder browsing and file browsing works as expected.
Risk
One public and one protected member are added. Existing behavior is not affected. Existing members (even private) still carry the same data. Minimal performance impact (most properties now change two fields) and minimal memory impact (one integer with corresponding generic type).
User code that processes "used" file dialogs could now be handed an instance that unexpectedly contains folders in the
FileName(s)properties. This, however, would have to be explicitly caused using new code. Unexpected file operations on folders (i.e. trying to open them) yield IO exceptions that the existing code should be already handling./cc @Symbai @ThomasGoulet73 @fabiant3