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
35 changes: 34 additions & 1 deletion specs/Storage.Pickers/FileOpenPicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ Supports specifying the initial location, extension filters, and text on commit

## Definition

```C#
```idl
runtimeclass FileOpenPicker
{
FileOpenPicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;
string Title;
string SettingsIdentifier;

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

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,13 @@ 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 0-based.
// When not specified, its value is null and the filter follows API's behavior. That is:
// When FileTypeFilter is in effect, auto-select the last one (All Files).
// Otherwise, auto-select the first one.
DefaultFileTypeIndex = 1u, // auto select Pictures

// (Optional) specify the view mode of the picker dialog. If not specified, defaults to List.
ViewMode = PickerViewMode.List,
};
Expand Down Expand Up @@ -109,6 +127,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 +144,13 @@ 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 0-based.
// When not specified, its value is null and the filter follows API's behavior. That is:
// When FileTypeFilter is in effect, auto-select the last one (All Files).
// Otherwise, auto-select the first one.
openPicker.DefaultFileTypeIndex(1u); // auto select Pictures

// (Optional) specify the view mode of the picker dialog. If not specified, defaults to List.
openPicker.ViewMode(PickerViewMode::List);
```
Expand Down
65 changes: 60 additions & 5 deletions specs/Storage.Pickers/FileSavePicker.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,23 @@ Represents a UI element that lets the user choose a file to save.

## Definition

```C#
```idl
runtimeclass FileSavePicker
{
FileSavePicker(Microsoft.UI.WindowId windowId);

string CommitButtonText;
string Title;
string SettingsIdentifier;

string DefaultFileExtension;
string SuggestedFileName;

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

Boolean ShowOverwritePrompt;
Boolean CreateNewFileIfNotExists;

string SuggestedFolder;
String SuggestedStartFolder;
Expand Down Expand Up @@ -64,14 +71,38 @@ 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" } }
{ "Text", new List<string> {".txt"} },
{ "Documents", new List<string> { ".doc", ".docx" } }
},

// (Optional) specify the index of the file type filter to be selected by default.
// The index is 0-based.
// When not specified, its value is null.
DefaultFileTypeIndex = 1u, // this will auto-select Documents

// (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,
Copy link
Contributor

Choose a reason for hiding this comment

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

CreateNewFileIfNotExists = true by default means the picker may create files as a side effect of a UI operation?
Combined with ShowOverwritePrompt = false, this could lead to accidental data creation or replacement.

Whether true is the safest default here?

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 @Saharsh979 , thanks for raising up this topic!

CreateNewFileIfnotExists = true is already the default behavior of FileSavePicker. This default behavior is consistent with that of the UWP FileSavePicker. Here we're making it customizable so that developers can choose to disable it.

Please note the FileSavePicker should only create a new file when the picked file doesn't exists ( #6023 and #6024 ensured this check ). Therefore, ShowOverwritePrompt doesn't conflict with CreateNewFileIfnotExists in any combination, for the former takes effects when the picked file exists, and the latter works when the picked file doesn't exist.

With the 2 properties, developers will have the flexibility in showing their own warning prompts. Kindly find more details here: #5976


// (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 +139,36 @@ 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" }));
savePicker.FileTypeChoices().Insert(L"Texts", winrt::single_threaded_vector<winrt::hstring>({ L".txt" }));
savePicker.FileTypeChoices().Insert(L"Documents", winrt::single_threaded_vector<winrt::hstring>({ L".doc", L".docx" }));

// (Optional) specify the index of the file type filter to be selected by default.
// The index is 0-based.
// When not specified, its value is null.
savePicker.DefaultFileTypeIndex(1u); // this will auto-select Documents

// (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
Loading