-
Notifications
You must be signed in to change notification settings - Fork 344
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
Public Spec for Microsoft.Windows.Storage.Pickers [Milestone 1] #5155
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
FileOpenPicker Class | ||
=== | ||
|
||
# Background | ||
|
||
Namespace: [Microsoft.Windows.Storage.Pickers](./Microsoft.Windows.Storage.Pickers.md) | ||
|
||
Represents a UI element that lets the user choose and open files. | ||
|
||
Supports specifying the initial location, extension filters, and text on commit button. | ||
|
||
# API Pages | ||
|
||
## Constructor | ||
|
||
### Attributes | ||
|
||
| **Attribute** | **Type** | **Description** | | ||
|--------------------------|---------------------------------------------------------|--------------------------------------------------------------------------| | ||
| `ViewMode` | [Microsoft::Windows::Storage::Pickers::PickerViewMode](./PickerViewMode.md) | Gets or sets the view mode that the file picker is using to present items. | | ||
| `SuggestedStartLocation` | [Microsoft::Windows::Storage::Pickers::PickerLocationId](./PickerLocationId.md)| Gets or sets the initial location where the file picker looks for files. | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a chance It would be a bummer if this limitation, that only applies to the UWP picker and UWP apps and not the COM picker, would be retained. From history, if it's not being addressed now, it will forever stay like that :/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw: It's certainly a feature that would be much appreciated as @whiskhub said. There is a quite popular issue dotnet/maui#9212 on the MAUI side asking for this feature. A person did a great research into it here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, a SuggestedStartLocationDirectory would be very useful. If you don't implement that, please at least implement the SettingsIdentifier, otherwise the start location will be even less customizable than in UWP. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi WinAppSDK friends @whiskhub , @MartyIX , @benstevens48 . The string input of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
You are, to a degree, as the spec is a consistent subset of * I can see why the Continue properties/methods are omitted. It's the others I find puzzling if consistency is the goal. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am just afraid that "wishlist for future milestones" practically means "never" 😅 which means I'd "never" be able to use this picker :/ |
||
| `CommitButtonText` | `winrt::hstring` | Gets or sets the text displayed on the commit button of the file picker. | | ||
| `FileTypeFilter` | `Windows::Foundation::Collections::IVector<hstring>` | Gets the collection of file types that the file picker displays. | | ||
|
||
### Examples | ||
C# | ||
|
||
```csharp | ||
using Microsoft.Windows.Storage.Pickers; | ||
|
||
var openPicker = new FileOpenPicker(this.AppWindow.Id) | ||
{ | ||
// (Optional) specify the initial location. If not specified, use system default: | ||
SuggestedStartLocation = PickerLocationId.DocumentsLibrary, | ||
|
||
// (Optional) specify the text displayed on commit button. If not specified, use system default: | ||
CommitButtonText = "Choose selected files", | ||
|
||
// (Optional) specify file extensions filters. If not specified, default to all (*.*) | ||
FileTypeFilter = { ".txt", ".pdf", ".doc", ".docx" }, | ||
}; | ||
``` | ||
|
||
C++ | ||
|
||
```cpp | ||
#include <winrt/Microsoft.Windows.Storage.Pickers.h> | ||
using namespace winrt::Microsoft::Windows::Storage::Pickers; | ||
|
||
FileOpenPicker openPicker(AppWindow().Id()); | ||
|
||
// (Optional) specify the initial location. If not specified, use system default: | ||
openPicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary); | ||
|
||
// (Optional) specify the text displayed on commit button. If not specified, use system default: | ||
openPicker.CommitButtonText(L"Choose selected files"); | ||
|
||
// (Optional) specify file extensions filters. If not specified, default to all (*.*) | ||
openPicker.FileTypeFilter().Append(L".txt"); | ||
openPicker.FileTypeFilter().Append(L".pdf"); | ||
openPicker.FileTypeFilter().Append(L".doc"); | ||
openPicker.FileTypeFilter().Append(L".docx"); | ||
``` | ||
## FileOpenPicker.PickSingleFilesAsync | ||
Displays a UI element that allows user to choose and open one file. | ||
### Definition | ||
```cpp | ||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> PickSingleFileAsync(); | ||
``` | ||
Return null if the file dialog was cancelled or closed without selection. | ||
|
||
### Examples | ||
|
||
C# | ||
|
||
```csharp | ||
using Microsoft.Windows.Storage.Pickers; | ||
|
||
var openPicker = new FileOpenPicker(this.AppWindow.Id); | ||
|
||
var file = await openPicker.PickSingleFileAsync(); | ||
if (file is not null) | ||
{ | ||
var content = System.IO.File.ReadAllText(file.Path); | ||
} | ||
else | ||
{ | ||
// error handling. | ||
} | ||
``` | ||
|
||
C++ | ||
```cpp | ||
#include <winrt/Microsoft.Windows.Storage.Pickers.h> | ||
#include <fstream> | ||
#include <string> | ||
using namespace winrt::Microsoft::Windows::Storage::Pickers; | ||
|
||
FileOpenPicker openPicker(AppWindow().Id()); | ||
auto& file = co_await openPicker.PickSingleFileAsync(); | ||
if (file != nullptr) | ||
{ | ||
std::ifstream fileReader(file.Path().c_str()); | ||
std::string text((std::istreambuf_iterator<char>(fileReader)), std::istreambuf_iterator<char>()); | ||
winrt::hstring hText = winrt::to_hstring(text); | ||
} | ||
else | ||
{ | ||
// error handling. | ||
} | ||
``` | ||
|
||
## FileOpenPicker.PickMultipleFilesAsync | ||
|
||
Displays a UI element that allows user to choose and open multiple files. | ||
|
||
### Definition | ||
```cpp | ||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Storage::StorageFile>> PickMultipleFilesAsync(); | ||
``` | ||
Return an empty list (Count = 0) if the file dialog's cancelled or closed. | ||
|
||
### Examples | ||
|
||
C# | ||
|
||
```csharp | ||
using Microsoft.Windows.Storage.Pickers; | ||
|
||
var openPicker = new FileOpenPicker(this.AppWindow.Id); | ||
|
||
var files = await openPicker.PickMultipleFilesAsync(); | ||
if (files is not null) | ||
{ | ||
var pickedFilePaths = files.Select(f => f.Path); | ||
foreach (var path in pickedFilePaths) | ||
{ | ||
var content = System.IO.File.ReadAllText(path); | ||
} | ||
} | ||
else | ||
{ | ||
// error handling. | ||
} | ||
``` | ||
|
||
C++ | ||
```cpp | ||
#include <winrt/Microsoft.Windows.Storage.Pickers.h> | ||
#include <fstream> | ||
#include <string> | ||
using namespace winrt::Microsoft::Windows::Storage::Pickers; | ||
|
||
FileOpenPicker openPicker(AppWindow().Id()); | ||
auto& files = co_await openPicker.PickMultipleFilesAsync(); | ||
if (files.Size() > 0) | ||
{ | ||
for (auto const& file : files) | ||
{ | ||
std::ifstream fileReader(file.Path().c_str()); | ||
std::string text((std::istreambuf_iterator<char>(fileReader)), std::istreambuf_iterator<char>()); | ||
winrt::hstring hText = winrt::to_hstring(text); | ||
} | ||
} | ||
else | ||
{ | ||
// error handling. | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
FileSavePicker Class | ||
=== | ||
|
||
# Background | ||
|
||
Namespace: [Microsoft.Windows.Storage.Pickers](./Microsoft.Windows.Storage.Pickers.md) | ||
|
||
Represents a UI element that lets the user choose a file to save. | ||
|
||
# API Pages | ||
|
||
## Constructor | ||
|
||
### Attributes | ||
|
||
| **Attribute** | **Type** | **Description** | | ||
|----------------------------|--------------------|-------------------| | ||
| `ViewMode` | [Microsoft::Windows::Storage::Pickers::PickerViewMode](./PickerViewMode.md) | Gets or sets the view mode that the file picker is using to present items. | | ||
| `SuggestedStartLocation` | [Microsoft::Windows::Storage::Pickers::PickerLocationId](./PickerLocationId.md)| Gets or sets the initial location where the file picker looks for files. | | ||
| `SuggestedFileName` | `winrt::hstring` | Gets or sets the file name displayed in the file name input box on launching the dialog. | | ||
| `DefaultFileExtension` | `winrt::hstring` | Gets or sets the file extension tailing the suggested file name in the file name input box on launching the dialog. | | ||
| `CommitButtonText` | `winrt::hstring` | Gets or sets the text displayed on the commit button of the file picker. | | ||
| `FileTypeChoices` | `winrt::Windows::Foundation::Collections::IMap<hstring, winrt::Windows::Foundation::Collections::IVector<hstring>>` | The file extensions categorized by purpose.| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why 'choices'? Windows.Storage.Pickers.FileOpenPicker calls it FileTypeFilter. IFileDialog and WinForms call it Extension. Haven't looked up WPF and others naming. Windows. WinRT naming seems a good fit. Why invent new terminology? SUGGESTION: Rename |
||
|
||
|
||
### Examples | ||
C# | ||
|
||
```csharp | ||
using Microsoft.Windows.Storage.Pickers; | ||
|
||
var savePicker = new FileSavePicker(this.AppWindow.Id) | ||
{ | ||
// (Optional) specify the initial location. If not specified, use system default: | ||
SuggestedStartLocation = PickerLocationId.DocumentsLibrary, | ||
|
||
// (Optional) specify the default file name. If not specified, use system default: | ||
SuggestedFileName = "My Document", | ||
|
||
// (Optional) specify the text displayed on commit button. If not specified, use system default: | ||
CommitButtonText = "Save Document", | ||
|
||
// (Optional) categorized extensions types. If not specified, use system default: All Files (*.*) | ||
FileTypeChoices = { | ||
{ "Documents", new List<string> { ".txt", ".doc", ".docx" } } | ||
}, | ||
|
||
// (Optional) specify the default file extension (will be appended after the default file name). | ||
// If not specified, will not appended after the default extension. | ||
DefaultFileExtension = ".txt", | ||
}; | ||
``` | ||
|
||
C++ | ||
|
||
```cpp | ||
#include <winrt/Microsoft.Windows.Storage.Pickers.h> | ||
using namespace winrt::Microsoft::Windows::Storage::Pickers; | ||
|
||
FileSavePicker savePicker(AppWindow().Id()); | ||
|
||
// (Optional) specify the initial location. If not specified, use system default: | ||
savePicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary); | ||
|
||
// (Optional) specify the default file name. If not specified, use system default: | ||
savePicker.SuggestedFileName(L"NewDocument"); | ||
|
||
// (Optional) categorized extensions types. If not specified, use system default: All Files (*.*) | ||
savePicker.FileTypeChoices().Insert(L"Text", winrt::single_threaded_vector<winrt::hstring>({ L".txt" })); | ||
|
||
// (Optional) specify the default file extension (will be appended after the default file name). | ||
// If not specified, will not appended after the default extension. | ||
savePicker.DefaultFileExtension(L".txt"); | ||
``` | ||
|
||
## FileSavePicker.PickSaveFileAsync | ||
|
||
Displays a UI element that allows the user to configure the file path to save. | ||
|
||
### Definition | ||
```cpp | ||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> PickSaveFileAsync(); | ||
``` | ||
Return null if the file dialog was cancelled or closed without selection. | ||
|
||
### Examples | ||
|
||
C# | ||
|
||
```csharp | ||
using Microsoft.Windows.Storage.Pickers; | ||
|
||
var savePicker = new FileSavePicker(this.AppWindow.Id); | ||
var file = await savePicker.PickSaveFileAsync(); | ||
if (file is not null) | ||
{ | ||
System.IO.File.WriteAllText(file.Path, "Hello world."); | ||
} | ||
else | ||
{ | ||
// error handling. | ||
} | ||
``` | ||
|
||
C++ | ||
|
||
```cpp | ||
#include <winrt/Microsoft.Windows.Storage.Pickers.h> | ||
#include <fstream> | ||
#include <string> | ||
using namespace winrt::Microsoft::Windows::Storage::Pickers; | ||
|
||
FileSavePicker savePicker(AppWindow().Id()); | ||
StorageFile file& = co_await savePicker.PickSaveFileAsync(); | ||
if (file != nullptr) | ||
{ | ||
std::ofstream outFile(file.Path().c_str()); | ||
outFile << "Hello world."; | ||
outFile.close(); | ||
} | ||
else | ||
{ | ||
// error handling. | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,100 @@ | ||||||
FolderPicker Class | ||||||
=== | ||||||
|
||||||
# Background | ||||||
|
||||||
Namespace: [Microsoft.Windows.Storage.Pickers](./Microsoft.Windows.Storage.Pickers.md) | ||||||
|
||||||
Represents a UI element that lets the user choose a folder. | ||||||
|
||||||
Supports specifying the initial location and text on commit button. | ||||||
|
||||||
# API Pages | ||||||
|
||||||
## Constructor | ||||||
|
||||||
### Attributes | ||||||
|
||||||
| **Attribute** | **Type** | **Description** | | ||||||
|----------------------------|--------------------|-------------------| | ||||||
| `ViewMode` | [Microsoft::Windows::Storage::Pickers::PickerViewMode](./PickerViewMode.md) | Gets or sets the view mode that the file picker is using to present items. | | ||||||
| `SuggestedStartLocation` | [Microsoft::Windows::Storage::Pickers::PickerLocationId](./PickerLocationId.md)| Gets or sets the initial location where the file picker looks for files. | | ||||||
| `CommitButtonText` | `winrt::hstring` | Gets or sets the text displayed on the commit button of the file picker. | | ||||||
|
||||||
### Examples | ||||||
|
||||||
C# | ||||||
|
||||||
```csharp | ||||||
using Microsoft.Windows.Storage.Pickers; | ||||||
|
||||||
var folderPicker = new FolderPicker(this.AppWindow.Id) | ||||||
{ | ||||||
// (Optional) specify the initial location. If not specified, use system default: | ||||||
SuggestedStartLocation = PickerLocationId.DocumentsLibrary, | ||||||
|
||||||
// (Optional) specify the text displayed on commit button. If not specified, use system default: | ||||||
CommitButtonText = "Select Folder", | ||||||
}; | ||||||
``` | ||||||
|
||||||
C++ | ||||||
|
||||||
```cpp | ||||||
#include <winrt/Microsoft.Windows.Storage.Pickers.h> | ||||||
using namespace winrt::Microsoft::Windows::Storage::Pickers; | ||||||
|
||||||
FolderPicker folderPicker(AppWindow().Id()); | ||||||
|
||||||
// (Optional) specify the initial location. If not specified, use system default: | ||||||
folderPicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary); | ||||||
|
||||||
// (Optional) specify the text displayed on commit button. If not specified, use system default: | ||||||
folderPicker.CommitButtonText(L"Select Folder"); | ||||||
``` | ||||||
|
||||||
## FolderPicker.PickSingleFolderAsync | ||||||
|
||||||
Displays a UI element that allows the user to choose a folder. | ||||||
|
||||||
### Definition | ||||||
```cpp | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WinRT APIs should be defined as MIDL3. Examples are written in specific languages (usually C#). Non-WinRT APIs are defined in their specific language, in the rare event a WinAppSDK API isn't WinRT. RECOMMEND: Define as MIDL3, not any specific language namespace Windows.Storage.Pickers
{
Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFolder> PickSingleFolderAsync();
} |
||||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFolder> PickSingleFolderAsync(); | ||||||
``` | ||||||
Return null if the file dialog was cancelled or closed without selection. | ||||||
|
||||||
Comment on lines
+64
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment should be 'Returns null if the file dialog was cancelled or closed without selection.'
Suggested change
Copilot is powered by AI, so mistakes are possible. Review output carefully before use. |
||||||
### Examples | ||||||
|
||||||
C# | ||||||
|
||||||
```csharp | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @codendone do you recall that conversation we had. Did it end with same comment applies throughout |
||||||
using Microsoft.Windows.Storage.Pickers; | ||||||
|
||||||
var folderPicker = new FolderPicker(this.AppWindow.Id); | ||||||
var folder = await folderPicker.PickSingleFolderAsync(); | ||||||
if (folder is not null) | ||||||
{ | ||||||
var path = folder.Path; | ||||||
} | ||||||
else | ||||||
{ | ||||||
// error handling. | ||||||
} | ||||||
``` | ||||||
|
||||||
C++ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You provided a C# example. Why also a C++ example? The norm is a C# example and only add other languages if they pose additional or different needs beyond mere syntax. Here' the C# and C++ examples are the same just language syntax differences. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @DrusTheAxe The reason for including both C# and C++ examples in the documentation is to cater to a broader audience. While the examples may only differ in syntax, providing both versions can help developers who are more comfortable with one language over the other. This approach is not unique to our specs. We have several other documents that provide examples in both languages, such as the CameraCaptureUI.md |
||||||
```cpp | ||||||
#include <winrt/Microsoft.Windows.Storage.Pickers.h> | ||||||
using namespace winrt::Microsoft::Windows::Storage::Pickers; | ||||||
|
||||||
FolderPicker folderPicker(AppWindow().Id()); | ||||||
auto& folder = co_await folderPicker.PickSingleFolderAsync(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ES.23: Prefer the {}-initializer syntax Same comments applies throughout |
||||||
if (folder != nullptr) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Examples should use Modern C++
|
||||||
{ | ||||||
auto path = folder.Path(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
} | ||||||
else | ||||||
{ | ||||||
// error handling. | ||||||
} | ||||||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec is split across multiple files, with their definitions (IDL) likewise split across multiple files. This complicates reviewing (and holistically understanding) the design and details.
Do you intend to have multiple .idl files in the implementation?
CONSIDER: Moving all the definitions to a single file, ideally as an
# API
section in Microsoft.Windows.Storage.Pickers.mdThat will also address gaps e.g. where's the API contract details?