Skip to content

Conversation

DinahK-2SO
Copy link
Contributor

@DinahK-2SO DinahK-2SO commented Aug 29, 2025

This is a design spec for adding new functionality to the Microsoft.Windows.Storage.Pickers APIs, focusing on improving how the initial folder and file type filters are specified. The main enhancements include introducing a SuggestedDefaultFolder property for all pickers to allow setting an absolute initial folder path, and adding support for categorized file type choices in FileOpenPicker. Documentation and code samples have been updated to reflect these changes.

This pull request updates the API surface and documentation for the FileOpenPicker, FileSavePicker, and FolderPicker classes to introduce a new SuggestedStartFolder property for all pickers, and adds a new FileTypeChoices property for FileOpenPicker. These changes allow developers to set an initial folder by absolute path and, for file open dialogs, to group file types into labeled categories. The documentation is updated to clarify property precedence and provide usage examples.

New picker properties and behavior

  • Added SuggestedStartFolder property to FileOpenPicker, FileSavePicker, and FolderPicker, allowing the initial folder to be set by absolute path. If the folder exists, it takes precedence over SuggestedStartLocation; if not, the picker falls back to SuggestedStartLocation and then the system default. [1] [2] [3] [4] [5] [6] [7]

  • Added FileTypeChoices property to FileOpenPicker, enabling grouping of file types into labeled choices. When both FileTypeChoices and FileTypeFilter are provided, FileTypeChoices takes precedence. [1] [2] [3] [4]

Documentation and usage examples

  • Updated C# and C++/WinRT code samples for all pickers to demonstrate usage of SuggestedStartFolder, including notes about its precedence over SuggestedStartLocation. [1] [2] [3] [4] [5] [6]

  • Enhanced FileOpenPicker and FileSavePicker examples to show how to use FileTypeChoices and clarified that it overrides FileTypeFilter if both are set. [1] [2] [3]

  • Added notes sections to the documentation for all pickers to explicitly state the precedence rules for SuggestedStartFolder and FileTypeChoices. [1] [2]

These changes make the picker APIs more flexible and the documentation clearer for developers.

@DinahK-2SO DinahK-2SO changed the title API review for new properties in Storage.Pickers API review for new properties in Storage.Pickers - SuggestedDefaultFolder, FileTypeChoices Aug 29, 2025
// (Optional) set an initial folder by absolute path.
// Takes precedence over SuggestedStartLocation when both defined.
// If this folder is not found, falls back to SuggestedStartLocation.
SuggestedStartFolder = @"C:\\MyFiles",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @"C:\\MyFiles" should have a single backslash, given the '@'. (Same comment also for the other pickers.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake - I'll update it. Thanks for pointing it out! @codendone

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest iteration.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RECOMMENDED: fix.

FileTypeChoices = new Dictionary<string, IList<string>>
{
{ "Documents", new List<string> { ".txt", ".doc", ".docx" } },
{ "Pictures", new List<string> { ".png", ".jpg", ".jpeg", ".bmp" } }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This design is tricky because the app is providing the IList, and it could provide one that behaves erratically. (E.g., reports the wrong Size, or one that generates different extensions each time you ask, or one that makes a cross-process COM call when you ask for an item.) We have to be careful how we access the list elements to be resilient to misbehaving list implementations.

class WeirdList : IList<string>
{
    public int Count => Math.Random(0, 10);
    public bool IsReadOnly => true;
    public Item[int index] => GenerateRandomString();
}

Also, how do you set this in JavaScript or Python? I don't think they have a way to create IList implementations.

But it seems that this already exists in the FileSavePicker, so hopefully we can use the same solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @oldnewthing , thanks for pointing out. The API here should be IVector instead of IList. The sample code is wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest iteration.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed api is:

IMap<string, IVector<string>> FileTypeChoices{ get; };

This matches the existing Windows.Storage.Pickers.FileSavePicker.
We could diverge from what is in the system type if there was a strong motivation to do so but the current proposal seems reasonable.

RECOMMENDED: stick with IVector

// (Optional) set an initial folder by absolute path.
// Takes precedence over SuggestedStartLocation when both defined.
// If not found, falls back to SuggestedStartLocation.
openPicker.SuggestedStartFolder(L"C:\\MyFiles");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe SuggestedStartFolderPath to emphasize that it's a path, and not an IStorageFolder.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @oldnewthing , FileSavePicker already includes a SuggestedFolder property, which is also of type string. To maintain consistency, would it make sense to name the new property SuggestedStartFolder instead of SuggestedStartFolderPath? Happy to hear your thoughts!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we have already shipped with SuggestedFolder, let's maintain consistency here.

RECOMMENDED: keep SuggestedStartFolder.

@@ -85,7 +96,7 @@ savePicker.SuggestedFileName(L"NewDocument");

// (Optional) Sets the folder that the file save dialog displays when it opens.
// If not specified or the specified path doesn't exist, defaults to the last folder the user visited.
savePicker.SuggestedFolder = L"C:\\MyFiles",
savePicker.SuggestedFolder(L"C:\\MyFiles");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between FileSavePicker.SuggestedStartFolder and FileSavePicker.SuggestedFolder? They seem to do the same thing.

Should we simply continue using FileSavePicker.SuggestedFolder (and not add FileSavePicker.SuggestedStartFolder), and add FileOpenPicker.SuggestedFolder + FolderPicker.SuggestedFolder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @oldnewthing , Thanks for raising this point!

SuggestedFolder means the path will be always tried to open, regardless of user's operation. ( Under the hood, it uses the SetFolder method of COM APIs)

Meanwhile, SuggestedStartFolder is the path shown the first time the user launches the picker - usually when the app is newly installed. After user has picked a file, if the picker is launched again later, it will open the user's last selected folder, and SuggestedStartFolder will be silent. ( It corresponds to the SetDefaultFolder method in the COM API . )

The effective time span of SuggestedStartFolder is the same as that of SuggestedStartLocation.

Copy link
Contributor Author

@DinahK-2SO DinahK-2SO Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this explanation in example code comments.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a pretty subtle distinction that would not be obvious to someone casually reading the descriptions. I would update the Notes section with a paragraph explaining the functional difference between the two.

RECOMMENDED: Clarify distinction between SuggestedStartFolder and SuggestedFolder.

@@ -19,8 +19,13 @@ runtimeclass FileOpenPicker
FileOpenPicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;

IMap<String, IVector<String>> FileTypeChoices{ get; };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @oldnewthing , the values of FileTypeChoices are IVector instead of IList. Would IVector help avoid the issues you mentioned below with IList? Just wanted to confirm if this design is safe. IVector is also the interface for existing FileSavePicker.FileTypeChoices

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dinah: note that IVector is a WinRT interface and will appear in the definition in the runtimeclass.
IList is a .net type and it is used as the projection of the WinRT IVector into C#.

So in your sample C# code you will use IList (or an implementation of that interface such as List).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants