-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
PickFolders option for OpenFileDialog #6351
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
FolderBrowserDialog
in 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_PICKFOLDERS
on 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_PICKFOLDERS
conflicts 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_EXPLORER
OFN_ENABLEHOOK
OFN_ENABLESIZING
For Vista dialogs, that is:
FOS_DEFAULTNOMINIMODE
FOS_FORCEFILESYSTEM
Using the existing infrastructure would mean either
OFN_EXPLORER
bit 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
OpenFileDialog
turns onCheckFileExists
by default. The property works as advertised, meaning users cannot confirm anything if only folders are available to pick. For convenience, setting thePickFolders
option has a side effect of unsetting theCheckFileExists
option.Existing properties on folder dialog
(excerpt from discussion in #4039)
These are the current public properties on the
FileDialog
.Applicable to folder selection:
CustomPlaces
DereferenceLinks
- whether links to folders are followed or not allowedFileName
- e.g. C:\Users\ThomasFileNames
- always has 1 item at the momentInitialDirectory
SafeFileName
- e.g. ThomasSafeFileNames
- always has 1 item at the momentTag
Title
Doing 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_NOVALIDATE
flag works in the legacy file dialogs. However, for the Vista dialogs, theFOS_NOVALIDATE
flag 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
DefaultExt
withAddExtensions
are 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):
Filter
FilterIndex
Existing methods on folder dialog
OpenFile
andOpenFiles
throwUnauthorisedAccessException
on folders. The existing code should already expect this type of exception when opening files.Legacy behavior
The code currently throws
PlatformNotSupported
exception on Windows XP. If that is acceptable, exception message needs to be added. If not, support forSHBrowseForFolder
API 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 wholeIFileDialog
API. #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