Skip to content
Open
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
31 changes: 31 additions & 0 deletions specs/Storage.Pickers/FileOpenPicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ runtimeclass FileOpenPicker
FileOpenPicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;
string Title;
string SettingsIdentifier;

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

string SuggestedFolder;
String SuggestedStartFolder;
Expand Down Expand Up @@ -65,6 +68,14 @@ 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) specify the title of the picker.
// If not specified, the system uses a default title.
Title = "Open File",

// (Optional) specify the settings identifier of the picker.
// It allows the picker to remember its state (e.g. size, location, etc) across sessions.
SettingsIdentifier = "MySettingsIdentifier",

// (Optional) group file types into labeled choices
// FileTypeChoices takes precedence over FileTypeFilter when both defined.
FileTypeChoices = {
Expand All @@ -75,6 +86,12 @@ var openPicker = new FileOpenPicker(this.AppWindow.Id)
// (Optional) specify file extension filters. If not specified, defaults to all files (*.*).
FileTypeFilter = { ".txt", ".pdf", ".doc", ".docx" },

// (Optional) specify the index of the file type filter to be selected by default. The index is 1-based.
// When it is 0 (the default value), the selected filter will be decided by API behavior. That is:
// When FileTypeFilter is in effect, auto-select the last one (All Files).
// Otherwise, auto-select the first one.
FileTypeIndex = 1,

// (Optional) specify the view mode of the picker dialog. If not specified, defaults to List.
ViewMode = PickerViewMode.List,
};
Expand Down Expand Up @@ -109,6 +126,14 @@ openPicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary);
// If not specified, the system uses a default label of "Open" (suitably translated).
openPicker.CommitButtonText(L"Choose selected files");

// (Optional) specify the title of the picker.
// If not specified, the system uses a default title.
openPicker.Title(L"Open File");

// (Optional) specify the settings identifier of the picker.
// It allows the picker to remember its state (e.g. size, location, etc) across sessions.
openPicker.SettingsIdentifier(L"MySettingsIdentifier");

// (Optional) group file types into labeled choices
// FileTypeChoices takes precedence over FileTypeFilter when both defined.
auto choices = openPicker.FileTypeChoices();
Expand All @@ -118,6 +143,12 @@ choices.Insert(L"Pictures", winrt::single_threaded_vector<winrt::hstring>({ L".p
// (Optional) specify file extension filters. If not specified, defaults to all files (*.*).
openPicker.FileTypeFilter().ReplaceAll({ L".txt", L".pdf", L".doc", L".docx" });

// (Optional) specify the index of the file type filter to be selected by default. The index is 1-based.
// When it is 0 (the default value), the selected filter will be decided by API behavior. That is:
// When FileTypeFilter is in effect, auto-select the last one (All Files).
// Otherwise, auto-select the first one.
openPicker.FileTypeIndex(1);

// (Optional) specify the view mode of the picker dialog. If not specified, defaults to List.
openPicker.ViewMode(PickerViewMode::List);
```
Expand Down
53 changes: 51 additions & 2 deletions specs/Storage.Pickers/FileSavePicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,17 @@ runtimeclass FileSavePicker
FileSavePicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;
string Title;
string SettingsIdentifier;

string DefaultFileExtension;
string SuggestedFileName;

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

Boolean ShowOverwritePrompt;
Boolean CreateNewFileIfNotExists;

string SuggestedFolder;
String SuggestedStartFolder;
Expand Down Expand Up @@ -64,14 +71,35 @@ var savePicker = new FileSavePicker(this.AppWindow.Id)
// If not specified, the system uses a default label of "Save" (suitably translated).
CommitButtonText = "Save Document",

// (Optional) specify the title of the picker.
// If not specified, the system uses a default title.
Title = "Save File",

// (Optional) specify the settings identifier of the picker.
// It allows the picker to remember its state (e.g. size, location, etc) across sessions.
SettingsIdentifier = "MySettingsIdentifier",

// (Optional) categorized extension types. If not specified, "All Files (*.*)" is allowed.
// Note that when "All Files (*.*)" is allowed, end users can save a file without an extension.
FileTypeChoices = {
{ "Documents", new List<string> { ".txt", ".doc", ".docx" } }
},

// (Optional) specify the index of the file type filter to be selected by default.
// The index is 1-based.
FileTypeIndex = 1,

// (Optional) Show a warning prompt of file overwrite when user tries to pick an existing file.
// set to true by default.
ShowOverwritePrompt = true,

// (Optional) create an empty file when the picked file does not yet exist.
// set to true by default.
CreateNewFileIfNotExists = true,

// (Optional) specify the default file extension (will be appended to SuggestedFileName).
// If not specified, no extension will be appended.
// Note: the default extension applies when the active filter is "All Files (*)" or includes multiple extensions, and the default extension is one of them.
// If not applied, no extension will be appended.
DefaultFileExtension = ".txt",
};
```
Expand Down Expand Up @@ -108,12 +136,33 @@ savePicker.SuggestedFileName(L"NewDocument");
// If not specified, the system uses a default label of "Save" (suitably translated).
savePicker.CommitButtonText(L"Save Document");

// (Optional) specify the title of the picker.
// If not specified, the system uses a default title.
savePicker.Title(L"Save File");

// (Optional) specify the settings identifier of the picker.
// It allows the picker to remember its state (e.g. size, location, etc) across sessions.
savePicker.SettingsIdentifier(L"MySettingsIdentifier");

// (Optional) categorized extension types. If not specified, "All Files (*.*)" is allowed.
// Note that when "All Files (*.*)" is allowed, end users can save a file without an extension.
savePicker.FileTypeChoices().Insert(L"Text", winrt::single_threaded_vector<winrt::hstring>({ L".txt" }));

// (Optional) specify the index of the file type filter to be selected by default.
// The index is 1-based.
savePicker.FileTypeIndex(1);

// (Optional) Show a warning prompt of file overwrite when user tries to pick an existing file.
// set to true by default.
savePicker.ShowOverwritePrompt(true);

// (Optional) create an empty file when the picked file does not yet exist.
// set to true by default.
savePicker.CreateNewFileIfNotExists(true);

// (Optional) specify the default file extension (will be appended to SuggestedFileName).
// If not specified, no extension will be appended.
// Note: the default extension applies when the selected filter is "All Files (*)" or includes multiple extensions, and the default extension is one of them.
// If not applied, no extension will be appended.
savePicker.DefaultFileExtension(L".txt");
```

Expand Down
71 changes: 71 additions & 0 deletions specs/Storage.Pickers/FolderPicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ runtimeclass FolderPicker
FolderPicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;
string Title;
string SettingsIdentifier;

string SuggestedFolder;
String SuggestedStartFolder;
Expand All @@ -27,6 +29,7 @@ runtimeclass FolderPicker
PickerViewMode ViewMode;

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

Expand Down Expand Up @@ -66,6 +69,14 @@ var folderPicker = new FolderPicker(this.AppWindow.Id)
// If not specified, the system uses a default label of "Open" (suitably translated).
CommitButtonText = "Select Folder",

// (Optional) specify the title of the picker.
// If not specified, the system uses a default title.
Title = "Select Folder",

// (Optional) specify the settings identifier of the picker.
// It allows the picker to remember its state (e.g. size, location, etc) across sessions.
SettingsIdentifier = "MySettingsIdentifier",

// (Optional) specify the view mode of the picker dialog. If not specified, default to List.
ViewMode = PickerViewMode.List,
};
Expand Down Expand Up @@ -100,6 +111,14 @@ folderPicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary);
// If not specified, the system uses a default label of "Open" (suitably translated).
folderPicker.CommitButtonText(L"Select Folder");

// (Optional) specify the title of the picker.
// If not specified, the system uses a default title.
folderPicker.Title(L"Select Folder");

// (Optional) specify the settings identifier of the picker.
// It allows the picker to remember its state (e.g. size, location, etc) across sessions.
folderPicker.SettingsIdentifier(L"MySettingsIdentifier");

// (Optional) specify the view mode of the picker dialog. If not specified, default to List.
folderPicker.ViewMode(PickerViewMode::List);
```
Expand Down Expand Up @@ -148,6 +167,58 @@ else
}
```

## FolderPicker.PickMultipleFoldersAsync

Displays a UI element that allows the user to choose multiple folders.

Returns a collection of lightweight objects that have the path of the picked folders.

Returns an empty list (`Count` = 0) if the folder dialog was cancelled or closed without a selection.

### Examples

C#

```C#
using Microsoft.Windows.Storage.Pickers;

var folderPicker = new FolderPicker(this.AppWindow.Id);

var results = await folderPicker.PickMultipleFoldersAsync();
if (results.Count > 0)
{
var pickedFolderPaths = results.Select(f => f.Path);
foreach (var path in pickedFolderPaths)
{
// Do something with the folder path
}
}
else
{
// error handling.
}
```

C++
```C++
#include <winrt/Microsoft.Windows.Storage.Pickers.h>
using namespace winrt::Microsoft::Windows::Storage::Pickers;

FolderPicker folderPicker(AppWindow().Id());
auto results{ co_await folderPicker.PickMultipleFoldersAsync() };
if (results.Size() > 0)
{
for (auto const& result : results)
{
auto path{ result.Path() };
}
}
else
{
// error handling.
}
```

# See Also

[PickFolderResult](./PickFolderResult.md)
Expand Down
26 changes: 26 additions & 0 deletions specs/Storage.Pickers/Microsoft.Windows.Storage.Pickers.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ to `SuggestedStartLocation`, then to the system default.
catagorized filter types. When both `FileTypeChoices` and `FileTypeFilter` are provided,
`FileTypeChoices` is used and `FileTypeFilter` is ignored.

1. Adding `FileTypeIndex` for `FileOpenPicker` and `FileSavePicker`. This allows setting the default selected file type filter index. Note this index is 1-based. When it is 0 (the default value), the selected filter might be override by the API's default behavior.
Copy link

Choose a reason for hiding this comment

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

It would be friendlier to developer to use 0-based index (-1 for default behavior), it will save lots of time where they assume the "index" was always 0-based.
Are there any issues with the 0-based index?


1. The property `SettingsIdentifier` for all 3 pickers will be available in the new Storage.Pickers APIs from WindowsAppSDK2.0. `SettingsIdentifier` allows the picker to remember its state (e.g. size, location, etc) across sessions. When two different apps use the same string for SettingsIdentifier property, they will have their respective independent states.

1. Adding `ShowOverwritePrompt` for `FileSavePicker`. This Boolean properties default to `true` and control whether the picker warns about overwriting when user picked an existing file via FileSavePicker.

1. Adding `CreateNewFileIfNotExists` for `FileSavePicker`. This Boolean properties default to `true` and control whether to auto-create the picked file when it doesn't exist.

1. Adding `Title` for all 3 pickers. `Title` allows setting the title of the picker dialog.

1. Adding `PickMultipleFoldersAsync` for `FolderPicker`. This allows selecting multiple folders in the folder picker dialog.


# Conceptual pages

# API
Expand Down Expand Up @@ -119,9 +132,12 @@ namespace Microsoft.Windows.Storage.Pickers
FileOpenPicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;
string Title;
string SettingsIdentifier;

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

string SuggestedFolder;
string SuggestedStartFolder;
Expand All @@ -138,10 +154,17 @@ namespace Microsoft.Windows.Storage.Pickers
FileSavePicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;
string Title;
string SettingsIdentifier;

string DefaultFileExtension;
string SuggestedFileName;

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

bool ShowOverwritePrompt;
bool CreateNewFileIfNotExists;

string SuggestedFolder;
string SuggestedStartFolder;
Expand All @@ -155,6 +178,8 @@ namespace Microsoft.Windows.Storage.Pickers
FolderPicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;
string Title;
string SettingsIdentifier;

string SuggestedFolder;
string SuggestedStartFolder;
Expand All @@ -163,6 +188,7 @@ namespace Microsoft.Windows.Storage.Pickers
PickerViewMode ViewMode;

Windows.Foundation.IAsyncOperation<PickFolderResult> PickSingleFolderAsync();
Windows.Foundation.IAsyncOperation<IVectorView<PickFolderResult>> PickMultipleFoldersAsync();
}
}
```
Expand Down