Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions specs/Storage.Pickers/FileOpenPicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ runtimeclass FileOpenPicker
FileOpenPicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;

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

string SuggestedFolder;
String SuggestedStartFolder;
PickerLocationId SuggestedStartLocation;

PickerViewMode ViewMode;

Windows.Foundation.IAsyncOperation<PickFileResult> PickSingleFileAsync();
Expand All @@ -38,6 +44,18 @@ using Microsoft.Windows.Storage.Pickers;

var openPicker = new FileOpenPicker(this.AppWindow.Id)
{
// (Optional) Sets the folder that the file dialog always tries to display when it opens.
// SuggestedFolder will not be overriden by the last picked folder.
// If not specified, or the specified path doesn't exist, defaults to the last folder the user picked.
// On first launch of the picker, SuggestedFolder takes precedence over the SuggestedStartFolder if both set.
SuggestedFolder = @"C:\MyFiles",

// (Optional) Sets an initial folder path shown when the picker is first launched.
// Once the user has picked from a directory, SuggestedStartFolder will be silently ignored.
// Takes precedence over SuggestedStartLocation when both defined.
// If this folder is not found, falls back to SuggestedStartLocation.
SuggestedStartFolder = @"C:\MyFiles",

// (Optional) Specify the initial location for the picker.
// If the specified location doesn't exist on the user's machine, it falls back to the DocumentsLibrary.
// If not set, it defaults to PickerLocationId.Unspecified, and the system will use its default location.
Expand All @@ -47,6 +65,13 @@ var openPicker = new FileOpenPicker(this.AppWindow.Id)
// If not specified, the system uses a default label of "Open" (suitably translated).
CommitButtonText = "Choose selected files",

// (Optional) group file types into labeled choices
// FileTypeChoices takes precedence over FileTypeFilter when both defined.
FileTypeChoices = {
{ "Documents", new List<string> { ".txt", ".doc", ".docx" } },
{ "Pictures", new List<string> { ".png", ".jpg", ".jpeg", ".bmp" } }
},

// (Optional) specify file extension filters. If not specified, defaults to all files (*.*).
FileTypeFilter = { ".txt", ".pdf", ".doc", ".docx" },

Expand All @@ -63,6 +88,18 @@ using namespace winrt::Microsoft::Windows::Storage::Pickers;

FileOpenPicker openPicker(AppWindow().Id());

// (Optional) Sets the folder that the file dialog always tries to display when it opens.
// SuggestedFolder will not be overriden by the last picked folder.
// If not specified, or the specified path doesn't exist, defaults to the last folder the user picked.
// On first launch of the picker, SuggestedFolder takes precedence over the SuggestedStartFolder if both set.
openPicker.SuggestedFolder(L"C:\\MyFiles");

// (Optional) Sets an initial folder path shown when the picker is first launched.
// Once the user has picked from a directory, SuggestedStartFolder will be silently ignored.
// Takes precedence over SuggestedStartLocation when both defined.
// If this folder is not found, falls back to SuggestedStartLocation.
openPicker.SuggestedStartFolder(L"C:\\MyFiles");

// (Optional) Specify the initial location for the picker.
// If the specified location doesn't exist on the user's machine, it falls back to the DocumentsLibrary.
// If not set, it defaults to PickerLocationId.Unspecified, and the system will use its default location.
Expand All @@ -72,6 +109,12 @@ openPicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary);
// If not specified, the system uses a default label of "Open" (suitably translated).
openPicker.CommitButtonText(L"Choose selected files");

// (Optional) group file types into labeled choices
// FileTypeChoices takes precedence over FileTypeFilter when both defined.
auto choices = openPicker.FileTypeChoices();
choices.Insert(L"Documents", winrt::single_threaded_vector<winrt::hstring>({ L".txt", L".doc", L".docx" }));
choices.Insert(L"Pictures", winrt::single_threaded_vector<winrt::hstring>({ L".png", L".jpg", L".jpeg", L".bmp" }));

// (Optional) specify file extension filters. If not specified, defaults to all files (*.*).
openPicker.FileTypeFilter().ReplaceAll({ L".txt", L".pdf", L".doc", L".docx" });

Expand Down
35 changes: 26 additions & 9 deletions specs/Storage.Pickers/FileSavePicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ runtimeclass FileSavePicker
string CommitButtonText;
string DefaultFileExtension;
string SuggestedFileName;
string SuggestedFolder;

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

string SuggestedFolder;
String SuggestedStartFolder;
PickerLocationId SuggestedStartLocation;

Windows.Foundation.IAsyncOperation<PickFileResult> PickSaveFileAsync();
Expand All @@ -39,6 +40,18 @@ using Microsoft.Windows.Storage.Pickers;

var savePicker = new FileSavePicker(this.AppWindow.Id)
{
// (Optional) Sets the folder that the file save dialog always tries to display when it opens.
// SuggestedFolder will not be overriden by the last picked folder.
// If not specified, or the specified path doesn't exist, defaults to the last folder the user picked.
// On first launch of the picker, SuggestedFolder takes precedence over the SuggestedStartFolder if both set.
SuggestedFolder = @"C:\MyFiles",

// (Optional) Sets an initial folder path shown when the picker is first launched.
// Once the user has picked from a directory, SuggestedStartFolder will be silently ignored.
// Takes precedence over SuggestedStartLocation when both defined.
// If this folder is not found, falls back to SuggestedStartLocation.
SuggestedStartFolder = @"C:\MyFiles",

// (Optional) Specify the initial location for the picker.
// If the specified location doesn't exist on the user's machine, it falls back to the DocumentsLibrary.
// If not set, it defaults to PickerLocationId.Unspecified, and the system will use its default location.
Expand All @@ -47,10 +60,6 @@ var savePicker = new FileSavePicker(this.AppWindow.Id)
// (Optional) specify the default file name. If not specified, use system default.
SuggestedFileName = "My Document",

// (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.
SuggestedFolder = @"C:\MyFiles",

// (Optional) specify the text displayed on the commit button.
// If not specified, the system uses a default label of "Save" (suitably translated).
CommitButtonText = "Save Document",
Expand All @@ -75,6 +84,18 @@ using namespace winrt::Microsoft::Windows::Storage::Pickers;

FileSavePicker savePicker(AppWindow().Id());

// (Optional) Sets the folder that the file save dialog always tries to display when it opens.
// SuggestedFolder will not be overriden by the last picked folder.
// If not specified, or the specified path doesn't exist, defaults to the last folder the user picked.
// On first launch of the picker, SuggestedFolder takes precedence over the SuggestedStartFolder if both set.
savePicker.SuggestedFolder(L"C:\\MyFiles");

// (Optional) Sets an initial folder path shown when the picker is first launched.
// Once the user has picked from a directory, SuggestedStartFolder will be silently ignored.
// Takes precedence over SuggestedStartLocation when both defined.
// If this folder is not found, falls back to SuggestedStartLocation.
savePicker.SuggestedStartFolder(L"C:\\MyFiles");

// (Optional) Specify the initial location for the picker.
// If the specified location doesn't exist on the user's machine, it falls back to the DocumentsLibrary.
// If not set, it defaults to PickerLocationId.Unspecified, and the system will use its default location.
Expand All @@ -83,10 +104,6 @@ savePicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary);
// (Optional) specify the default file name. If not specified, use system default.
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",

// (Optional) specify the text displayed on the commit button.
// If not specified, the system uses a default label of "Save" (suitably translated).
savePicker.CommitButtonText(L"Save Document");
Expand Down
31 changes: 31 additions & 0 deletions specs/Storage.Pickers/FolderPicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ runtimeclass FolderPicker

string CommitButtonText;

string SuggestedFolder;
String SuggestedStartFolder;
PickerLocationId SuggestedStartLocation;

PickerViewMode ViewMode;

Windows.Foundation.IAsyncOperation<PickFolderResult> PickSingleFolderAsync();
Expand All @@ -42,6 +45,18 @@ using Microsoft.Windows.Storage.Pickers;

var folderPicker = new FolderPicker(this.AppWindow.Id)
{
// (Optional) Sets the folder that the folder dialog always tries to display when it opens.
// SuggestedFolder will not be overriden by the last picked folder.
// If not specified, or the specified path doesn't exist, defaults to the last folder the user picked.
// On first launch of the picker, SuggestedFolder takes precedence over the SuggestedStartFolder if both set.
SuggestedFolder = @"C:\MyFiles",

// (Optional) Sets an initial folder path shown when the picker is first launched.
// Once the user has picked from a directory, SuggestedStartFolder will be silently ignored.
// Takes precedence over SuggestedStartLocation when both defined.
// If this folder is not found, falls back to SuggestedStartLocation.
SuggestedStartFolder = @"C:\MyFiles",

// (Optional) Specify the initial location for the picker.
// If the specified location doesn't exist on the user's machine, it falls back to the DocumentsLibrary.
// If not set, it defaults to PickerLocationId.Unspecified, and the system will use its default location.
Expand All @@ -64,6 +79,18 @@ using namespace winrt::Microsoft::Windows::Storage::Pickers;

FolderPicker folderPicker(AppWindow().Id());

// (Optional) Sets the folder that the folder dialog always tries to display when it opens.
// SuggestedFolder will not be overriden by the last picked folder.
// If not specified, or the specified path doesn't exist, defaults to the last folder the user picked.
// On first launch of the picker, SuggestedFolder takes precedence over the SuggestedStartFolder if both set.
folderPicker.SuggestedFolder(L"C:\\MyFiles");

// (Optional) Sets an initial folder path shown when the picker is first launched.
// Once the user has picked from a directory, SuggestedStartFolder will be silently ignored.
// Takes precedence over SuggestedStartLocation when both defined.
// If this folder is not found, falls back to SuggestedStartLocation.
folderPicker.SuggestedStartFolder(L"C:\\MyFiles");

// (Optional) Specify the initial location for the picker.
// If the specified location doesn't exist on the user's machine, it falls back to the DocumentsLibrary.
// If not set, it defaults to PickerLocationId.Unspecified, and the system will use its default location.
Expand Down Expand Up @@ -124,3 +151,7 @@ else
# See Also

[PickFolderResult](./PickFolderResult.md)

Notes:

- SuggestedStartFolder takes precedence over SuggestedStartLocation.
44 changes: 43 additions & 1 deletion specs/Storage.Pickers/Microsoft.Windows.Storage.Pickers.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ in elevated scenarios.*
1. *Similarly, the `FileSavePicker.SuggestedSaveFile` property (which returned a `StorageFile`)
has been replaced. Its functionality is now covered by two string properties: `SuggestedFolder` and
`SuggestedFileName`. These allow for suggesting the folder and file name for the save dialog.*
1. Also adding the `SuggestedFolder` property to `FileOpenPicker` and `FolderPicker`, to better
support a commonly requested scenario - setting a persistent folder for all pickers.
1. *All new pickers are designed specifically for desktop apps and use a `WindowId` property to
link the picker to its host window, replacing the `WinRT.Interop.InitializeWithWindow.Initialize`
pattern.*
Expand All @@ -46,6 +48,15 @@ because the new APIs are currently designed for desktop scenarios where each use
interactive session, and each session is completely independent of the other sessions on the device.
This is in contrast to Xbox One or other multi-user devices.*

1. Adding `SuggestedStartFolder` for all 3 pickers. This allows setting the initial folder with
an absolute folder path in string. When its specified folder exists, `SuggestedStartFolder`
takes precedence over `SuggestedStartLocation`; when its folder not found, the picker falls back
to `SuggestedStartLocation`, then to the system default.

1. Adding `FileTypeChoices` for `FileOpenPicker`. This allows the dialog of FileOpenPicker to have
catagorized filter types. When both `FileTypeChoices` and `FileTypeFilter` are provided,
`FileTypeChoices` is used and `FileTypeFilter` is ignored.

# Conceptual pages

# API
Expand Down Expand Up @@ -108,8 +119,14 @@ namespace Microsoft.Windows.Storage.Pickers
FileOpenPicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;

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

string SuggestedFolder;
string SuggestedStartFolder;
PickerLocationId SuggestedStartLocation;

PickerViewMode ViewMode;

Windows.Foundation.IAsyncOperation<PickFileResult> PickSingleFileAsync();
Expand All @@ -123,10 +140,11 @@ namespace Microsoft.Windows.Storage.Pickers
string CommitButtonText;
string DefaultFileExtension;
string SuggestedFileName;
string SuggestedFolder;

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

string SuggestedFolder;
string SuggestedStartFolder;
PickerLocationId SuggestedStartLocation;

Windows.Foundation.IAsyncOperation<PickFileResult> PickSaveFileAsync();
Expand All @@ -138,10 +156,34 @@ namespace Microsoft.Windows.Storage.Pickers

string CommitButtonText;

string SuggestedFolder;
string SuggestedStartFolder;
PickerLocationId SuggestedStartLocation;

PickerViewMode ViewMode;

Windows.Foundation.IAsyncOperation<PickFolderResult> PickSingleFolderAsync();
}
}
```

Note: **Understanding SuggestedStartFolder/SuggestedStartLocation vs SuggestedFolder:**

These two kinds of properties have fundamentally different behaviors in terms of when and how they
affect the picker:

- `SuggestedFolder` sets the path that will always be tried when opening the picker, regardless of
the user's previous operations. This uses the [SetFolder](https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfolder)
method of the underlying COM APIs and takes precedence over any user navigation history.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This was discussed before, but I'm forgetting the details. If the SuggestedFolder exists, are SuggestedStartFolder and SuggestedStartLocation both ignored/unused?

Choose a reason for hiding this comment

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


- `SuggestedStartFolder` sets the path shown only the first time the user launches the picker
(typically when the app is newly installed). After the user has picked a file, subsequent
launches of the picker will open to the user's last selected folder, and `SuggestedStartFolder`
becomes silent. This corresponds to the [SetDefaultFolder](https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setdefaultfolder)
method in the COM API.

The effective time span of `SuggestedStartFolder` is the same as that of `SuggestedStartLocation`,
both only influence the picker's initial behavior before user interaction establishes a
navigation history.

`SuggestedStartFolder` takes precedence over `SuggestedStartLocation` when both specified.