├── .config └── dotnet-tools.json ├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── codeql-analysis.yml │ └── dependabot-cake.yml ├── .gitignore ├── CODEOWNERS ├── LICENSE ├── Ookii.Dialogs.Wpf.sln ├── Ookii.Dialogs.Wpf.sln.DotSettings ├── README.md ├── SECURITY.md ├── assets ├── ookii-dialogs-deprecated-nuget.png ├── ookii-dialogs-wpf-nuget.png ├── ookii-dialogs.snk ├── sample-credential-dialog-win10.png ├── sample-folderbrowser-dialog-win10.png ├── sample-progress-dialog-win10.png ├── sample-task-dialog-command-links-win10.png └── sample-task-dialog-win10.png ├── build.cake ├── build.cmd ├── build.ps1 ├── build.sh ├── cake.config ├── global.json ├── nuget.config ├── sample └── Ookii.Dialogs.Wpf.Sample │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Ookii.Dialogs.Wpf.Sample.csproj │ ├── Properties │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings │ ├── app.manifest │ └── ookii.ico └── src ├── Ookii.Dialogs.Wpf ├── .editorconfig ├── AnimationResource.cs ├── ButtonType.cs ├── ComCtlv6ActivationContext.cs ├── CredentialDialog.bmp ├── CredentialDialog.cs ├── CredentialDialog.designer.cs ├── CredentialException.cs ├── DownlevelTextMode.cs ├── ExpandButtonClickedEventArgs.cs ├── GlobalSuppressions.cs ├── HyperlinkClickedEventArgs.cs ├── Interop │ ├── COMGuids.cs │ ├── ComDlgResources.cs │ ├── IProgressDialog.cs │ ├── ShellWrapperDefinitions.cs │ └── Win32Resources.cs ├── NativeMethods.cs ├── NativeMethods.json ├── NativeMethods.txt ├── Ookii.Dialogs.Wpf.csproj ├── ProgressBarState.cs ├── ProgressBarStyle.cs ├── ProgressDialog.bmp ├── ProgressDialog.cs ├── ProgressDialog.designer.cs ├── ProgressDialog.resx ├── ProgressDialogDoWorkEventArgs.cs ├── Properties │ ├── Resources.Designer.cs │ ├── Resources.resx │ └── XPThemes.manifest ├── ShellAnimation.cs ├── SpanExtensions.cs ├── TaskDialog.bmp ├── TaskDialog.cs ├── TaskDialog.designer.cs ├── TaskDialogButton.cs ├── TaskDialogButtonStyle.cs ├── TaskDialogDesigner.cs ├── TaskDialogIcon.cs ├── TaskDialogItem.cs ├── TaskDialogItem.designer.cs ├── TaskDialogItemClickedEventArgs.cs ├── TaskDialogItemCollection.cs ├── TaskDialogRadioButton.cs ├── TimerEventArgs.cs ├── VistaFileDialog.cs ├── VistaFileDialogEvents.cs ├── VistaFolderBrowserDialog.bmp ├── VistaFolderBrowserDialog.cs ├── VistaOpenFileDialog.bmp ├── VistaOpenFileDialog.cs ├── VistaSaveFileDialog.bmp └── VistaSaveFileDialog.cs └── Ookii.Dialogs ├── Ookii.Dialogs.csproj ├── build └── Ookii.Dialogs.targets └── buildMultiTargeting └── Ookii.Dialogs.targets /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "cake.tool": { 6 | "version": "2.0.0", 7 | "commands": [ 8 | "dotnet-cake" 9 | ] 10 | }, 11 | "minver-cli": { 12 | "version": "5.0.0", 13 | "commands": [ 14 | "minver" 15 | ] 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | end_of_line = unset 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 4 12 | 13 | [*.{proj,props,sln,targets,sql}] 14 | indent_style = tab 15 | 16 | [*.{dna,config,nuspec,xml,xsd,csproj,vcxproj,vcproj,targets,ps1,resx}] 17 | indent_size = 2 18 | 19 | [*.{cpp,h,def}] 20 | indent_style = tab 21 | 22 | [*.dotsettings] 23 | end_of_line = lf 24 | 25 | [*.sas] 26 | indent_style = tab 27 | end_of_line = lf 28 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set 2 | * text=auto 3 | 4 | # Explicitly declare files that should always be converted to LF regardless of platform 5 | *.sh text eol=lf 6 | *.dotsettings text eol=lf 7 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: augustoproiete 2 | tidelift: "nuget/Ookii.Dialogs.Wpf" 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "nuget" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | target-branch: "master" 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" 12 | target-branch: "master" 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | - develop 6 | - "feature/**" 7 | - "release/**" 8 | - "hotfix/**" 9 | tags: 10 | - "*.*.*" 11 | paths-ignore: 12 | - "README.md" 13 | 14 | pull_request: 15 | 16 | workflow_dispatch: 17 | 18 | env: 19 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true 20 | DOTNET_CLI_TELEMETRY_OPTOUT: true 21 | DOTNET_NOLOGO: true 22 | 23 | jobs: 24 | build: 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | job: 29 | - os: windows-2019 30 | build: ./build.cmd 31 | push: true 32 | - os: windows-2022 33 | build: ./build.cmd 34 | name: ${{ matrix.job.os }} 35 | runs-on: ${{ matrix.job.os }} 36 | steps: 37 | - name: Setup netcoreapp3.1 38 | uses: actions/setup-dotnet@v4.3.1 39 | with: 40 | dotnet-version: "3.1.415" 41 | - name: Setup net5.0 42 | uses: actions/setup-dotnet@v4.3.1 43 | with: 44 | dotnet-version: "5.0.403" 45 | - name: Setup net6.0 46 | uses: actions/setup-dotnet@v4.3.1 47 | with: 48 | dotnet-version: "6.0.100" 49 | - name: Run dotnet --info 50 | run: dotnet --info 51 | - uses: actions/checkout@v4.2.2 52 | with: 53 | fetch-depth: 0 54 | - name: Build 55 | run: ${{ matrix.job.build }} --verbosity=diagnostic --target=pack 56 | - name: Publish artifacts 57 | if: matrix.job.push && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')) 58 | uses: actions/upload-artifact@v4.6.2 59 | with: 60 | if-no-files-found: warn 61 | name: package 62 | path: artifact/nuget/**/* 63 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [master, release/*] 4 | 5 | pull_request: 6 | branches: [master, release/*] 7 | 8 | workflow_dispatch: 9 | 10 | env: 11 | DOTNET_NOLOGO: 1 12 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 13 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 14 | 15 | jobs: 16 | analyse: 17 | runs-on: windows-latest 18 | steps: 19 | - uses: actions/checkout@v4.2.2 20 | with: 21 | fetch-depth: 2 22 | - uses: github/codeql-action/init@v3 23 | - uses: github/codeql-action/autobuild@v3 24 | - uses: github/codeql-action/analyze@v3 25 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-cake.yml: -------------------------------------------------------------------------------- 1 | on: 2 | schedule: 3 | # every Sunday at 6am 4 | - cron: '0 6 * * SUN' 5 | 6 | workflow_dispatch: 7 | 8 | jobs: 9 | dependabot-cake: 10 | runs-on: ubuntu-20.04 11 | steps: 12 | - name: check/update cake dependencies 13 | uses: augustoproiete-actions/nils-org--dependabot-cake-action@v1.1.0 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #windows 2 | Thumbs.db 3 | 4 | #osx 5 | .DS_Store 6 | ._* 7 | 8 | #visual-studio 9 | .vs/ 10 | *.user 11 | *.suo 12 | *.tmp_proj 13 | *.cache 14 | *.vsdoc 15 | [Oo]bj/ 16 | [Bb]in/ 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | [Ll]og/ 20 | [Tt]emp/ 21 | 22 | #nuget 23 | *.nupkg 24 | **/packages/* 25 | 26 | #cake 27 | .cake/ 28 | /artifact/ 29 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @augustoproiete 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) C. Augusto Proiete 2018-2021 4 | Copyright (c) Sven Groot 2009-2018 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | 3. Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /Ookii.Dialogs.Wpf.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31903.59 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{85E0D2C3-A700-4A65-BFEA-1F9A29875419}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E248E2C9-CE4A-41D2-91A0-8F61AAB69247}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{B2AB57E4-0121-4AF9-A559-C53B442F33D8}" 11 | ProjectSection(SolutionItems) = preProject 12 | .editorconfig = .editorconfig 13 | .gitattributes = .gitattributes 14 | .gitignore = .gitignore 15 | build.cake = build.cake 16 | build.cmd = build.cmd 17 | build.ps1 = build.ps1 18 | build.sh = build.sh 19 | cake.config = cake.config 20 | CODEOWNERS = CODEOWNERS 21 | global.json = global.json 22 | LICENSE = LICENSE 23 | nuget.config = nuget.config 24 | assets\ookii-dialogs.snk = assets\ookii-dialogs.snk 25 | README.md = README.md 26 | SECURITY.md = SECURITY.md 27 | EndProjectSection 28 | EndProject 29 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ookii.Dialogs.Wpf.Sample", "sample\Ookii.Dialogs.Wpf.Sample\Ookii.Dialogs.Wpf.Sample.csproj", "{E38181B2-E8E5-466D-9099-33FE75B4CFA1}" 30 | EndProject 31 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ookii.Dialogs.Wpf", "src\Ookii.Dialogs.Wpf\Ookii.Dialogs.Wpf.csproj", "{D01B1D20-8F5B-4834-8E5C-C7EC6DD587D4}" 32 | EndProject 33 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ookii.Dialogs", "src\Ookii.Dialogs\Ookii.Dialogs.csproj", "{50E3F3F4-9AEC-4FF9-8CF9-99721A167EC3}" 34 | EndProject 35 | Global 36 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 37 | Debug|Any CPU = Debug|Any CPU 38 | Release|Any CPU = Release|Any CPU 39 | EndGlobalSection 40 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 41 | {E38181B2-E8E5-466D-9099-33FE75B4CFA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {E38181B2-E8E5-466D-9099-33FE75B4CFA1}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {E38181B2-E8E5-466D-9099-33FE75B4CFA1}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {E38181B2-E8E5-466D-9099-33FE75B4CFA1}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {D01B1D20-8F5B-4834-8E5C-C7EC6DD587D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {D01B1D20-8F5B-4834-8E5C-C7EC6DD587D4}.Debug|Any CPU.Build.0 = Debug|Any CPU 47 | {D01B1D20-8F5B-4834-8E5C-C7EC6DD587D4}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {D01B1D20-8F5B-4834-8E5C-C7EC6DD587D4}.Release|Any CPU.Build.0 = Release|Any CPU 49 | {50E3F3F4-9AEC-4FF9-8CF9-99721A167EC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 50 | {50E3F3F4-9AEC-4FF9-8CF9-99721A167EC3}.Debug|Any CPU.Build.0 = Debug|Any CPU 51 | {50E3F3F4-9AEC-4FF9-8CF9-99721A167EC3}.Release|Any CPU.ActiveCfg = Release|Any CPU 52 | {50E3F3F4-9AEC-4FF9-8CF9-99721A167EC3}.Release|Any CPU.Build.0 = Release|Any CPU 53 | EndGlobalSection 54 | GlobalSection(SolutionProperties) = preSolution 55 | HideSolutionNode = FALSE 56 | EndGlobalSection 57 | GlobalSection(NestedProjects) = preSolution 58 | {E38181B2-E8E5-466D-9099-33FE75B4CFA1} = {85E0D2C3-A700-4A65-BFEA-1F9A29875419} 59 | {D01B1D20-8F5B-4834-8E5C-C7EC6DD587D4} = {E248E2C9-CE4A-41D2-91A0-8F61AAB69247} 60 | {50E3F3F4-9AEC-4FF9-8CF9-99721A167EC3} = {E248E2C9-CE4A-41D2-91A0-8F61AAB69247} 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {C17C6EF5-4A5E-45BB-AFB9-2D0547C4D682} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /Ookii.Dialogs.Wpf.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | DO_NOT_SHOW 3 | DO_NOT_SHOW 4 | DO_NOT_SHOW 5 | <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> 6 | <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> 7 | True 8 | True 9 | True 10 | True 11 | True -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | README.md | 2 | |:---| 3 | 4 |
5 | 6 | Ookii.Dialogs.Wpf 7 | 8 |
9 | 10 |

Ookii.Dialogs.Wpf

11 |
12 | 13 | A class library for WPF applications providing several common dialogs. Included are classes for task dialogs, credential dialog, progress dialog, and common file dialogs. 14 | 15 | [![NuGet Version](http://img.shields.io/nuget/v/Ookii.Dialogs.Wpf.svg?style=flat)](https://www.nuget.org/packages/Ookii.Dialogs.Wpf) [![NuGet Downloads](https://img.shields.io/nuget/dt/Ookii.Dialogs.Wpf.svg)](https://www.nuget.org/packages/Ookii.Dialogs.Wpf) [![.NET](https://img.shields.io/badge/.NET%20-%3E%3D%205.0-512bd4)](https://dotnet.microsoft.com/download) [![.NET Core](https://img.shields.io/badge/.NET%20Core-%3E%3D%203.1-512bd4)](https://dotnet.microsoft.com/download) [![.NET Framework](https://img.shields.io/badge/.NET%20Framework-%3E%3D%204.5-512bd4)](https://dotnet.microsoft.com/download) 16 | 17 | [![codeql-analysis](https://github.com/ookii-dialogs/ookii-dialogs-wpf/workflows/.github/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ookii-dialogs/ookii-dialogs-wpf/actions?query=workflow%3A.github%2Fworkflows%2Fcodeql-analysis.yml) 18 | 19 |
20 | 21 | ## Give a Star! :star: 22 | 23 | If you like or are using this project please give it a star. Thanks! 24 | 25 | ## Getting started 26 | 27 | Install the [Ookii.Dialogs.Wpf](https://www.nuget.org/packages/Ookii.Dialogs.Wpf/) package from NuGet: 28 | 29 | ```powershell 30 | Install-Package Ookii.Dialogs.Wpf 31 | ``` 32 | 33 | The included sample application [`Ookii.Dialogs.Sample.Wpf`](sample/Ookii.Dialogs.Wpf.Sample/) demonstrate the dialogs for WPF. View the source of this application to see how to use the dialogs. 34 | 35 | ### Windows Forms compatibility 36 | 37 | If you're looking to use these common dialogs on a Windows Forms application, check out [Ookii.Dialogs.WinForms](https://github.com/ookii-dialogs/ookii-dialogs-winforms). 38 | 39 | ## Included dialogs 40 | 41 | ### Task dialog 42 | 43 | [Task dialogs](https://docs.microsoft.com/en-us/windows/desktop/Controls/task-dialogs-overview) are a new type of dialog first introduced in Windows Vista. They provide a superset of the message box functionality. 44 | 45 | ![A task dialog as it appears on Windows 10](assets/sample-task-dialog-win10.png) 46 | 47 | ![A task dialog with command links as it appears on Windows 10](assets/sample-task-dialog-command-links-win10.png) 48 | 49 | The `Ookii.Dialogs.Wpf.TaskDialog` class provide access to the task dialog functionality. The `TaskDialog` class inherits from `System.ComponentModel.Component` and offers full support for the Component designer of Visual Studio. 50 | 51 | The `TaskDialog` class requires Windows Vista or a later version of Windows. Windows XP is not supported. Note that it is safe to instantiate the `TaskDialog` class and set any of its properties; only when the dialog is shown will a `NotSupportedException` be thrown on unsupported operating systems. 52 | 53 | ### Progress dialog 54 | 55 | Progress dialogs are a common dialog to show progress during operations that may take a long time. They are used extensively in the Windows shell, and an API has been available since Windows 2000. 56 | 57 | ![A progress dialog as it appears on Windows 10](assets/sample-progress-dialog-win10.png) 58 | 59 | The `Ookii.Dialogs.Wpf.ProgressDialog` class provide a wrapper for the Windows progress dialog API. The `ProgressDialog` class inherits from `System.ComponentModel.Component` and offers full support for the Component designer of Visual Studio. The `ProgressDialog` class resembles the `System.ComponentModel.BackgroundWorker` class and can be used in much the same way as that class. 60 | 61 | The progress dialog's behaviour of the `ShowDialog` function is slightly different than that of other .NET dialogs; It is recommended to use a non-modal dialog with the `Show` function. 62 | 63 | The `ProgressDialog` class is supported on Windows XP and later versions of Windows. However, the progress dialog has a very different appearance on Windows Vista and later (the image above shows the Windows 10 version), so it is recommended to test on the operating systems your application is supported to see if it appears to your satisfaction. 64 | 65 | When using Windows 7 or later, the `ProgressDialog` class automatically provides progress notification in the application's task bar button. 66 | 67 | ### Credential dialog 68 | 69 | The `Ookii.Dialogs.Wpf.CredentialDialog` class provide wrappers for the `CredUI` functionality first introduced in Windows XP. This class provides functionality for saving and retrieving generic credentials, as well as displaying the credential UI dialog. This class does not support all functionality of `CredUI`; only generic credentials are supported, thing such as domain credentials or alternative authentication providers (e.g. smart cards or biometric devices) are not supported. 70 | 71 | ![A credential dialog as it appears on Windows 10](assets/sample-credential-dialog-win10.png) 72 | 73 | The `CredentialDialog` class inherits from `System.ComponentModel.Component` and offers full support for the Component designer of Visual Studio. 74 | 75 | On Windows XP, the `CredentialDialog` class will use the `CredUIPromptForCredentials` function to show the dialog; on Windows Vista and later, the `CredUIPromptForWindowsCredentials` function is used instead to show the new dialog introduced with Windows Vista. Because of the difference in appearance in the two versions (the image above shows the Vista version), it is recommended to test on both operating systems to see if it appears to your satisfaction. 76 | 77 | ### Vista-style common file dialogs 78 | 79 | Windows Vista introduced a new style of common file dialogs. As of .NET 3.5 SP1, the Windows Forms `OpenFileDialog` and `SaveFileDialog` class will automatically use the new style under most circumstances; however, some settings (such as setting `ShowReadOnly` to `true`) still cause it to revert to the old dialog. The `FolderBrowserDialog` still uses the old style. In WPF, the `Microsoft.Win32.OpenFileDialog` and `SaveFileDialog` classes still use the old style dialogs, and a folder browser dialog is not provided at all. 80 | 81 | ![The Vista-style folder browser dialog as it appears on Windows 10](assets/sample-folderbrowser-dialog-win10.png) 82 | 83 | The `Ookii.Dialogs.Wpf.VistaOpenFileDialog`, `Ookii.Dialogs.Wpf.VistaSaveFileDialog` and `Ookii.Dialogs.Wpf.VistaFolderBrowserDialog` classes provide these dialogs for WPF (note that in the case of the `OpenFileDialog` and `SaveFileDialog` it is recommended to use the built-in .NET classes unless you hit one of the scenarios where those classes use the old dialogs). 84 | 85 | The classes have been designed to resemble the original WPF classes to make it easy to switch. When the classes are used on Windows XP, they will automatically fall back to the old style dialog; this is also true for the `VistaFolderBrowserDialog`; that class provides a complete implementation of a folder browser dialog for WPF, old as well as new style. 86 | 87 | ## .NET Core 3.1 & .NET 5 pre-requisites **before** Ookii.Dialogs.Wpf v3.1.0 88 | 89 | > **NOTE: Starting with Ookii.Dialogs.Wpf v3.1.0 an app.manifest is no longer required when using in .NET 5 or .NET Core 3.1 apps** 90 | 91 | Ookii Dialogs leverages the components and visual styles of the Windows Common Controls library (`comctl32.dll`), and WPF applications targeting .NET Core 3.1 and/or .NET 5 must add an [application manifest](https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests) (`app.manifest`) to their projects with a reference to `Microsoft.Windows.Common-Controls`. 92 | 93 | Without the application manifest, you'll get an error with a message similar to the below: 94 | 95 | ``` 96 | System.EntryPointNotFoundException: 'Unable to find an entry point named '...' in DLL 'comctl32.dll'.' 97 | ``` 98 | 99 | In Visual Studio, you can right click on your project and go to Add -> New Item... and select `Application Manifest File (Windows Only)`. That will create a template that you can customize and delete the parts you don't want and/or uncomment the parts that you want. The only required part for Ookii Dialogs to work is the `dependentAssembly` entry with the `Microsoft.Windows.Common-Controls` dependency. 100 | 101 | ```xml 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 117 | 118 | 119 | 120 | ``` 121 | 122 | For more information, visit the following links: 123 | 124 | - [EntryPointNotFoundException when instantiating a TaskDialog](https://github.com/ookii-dialogs/ookii-dialogs-wpf/issues/23) 125 | - [WPF System.EntryPointNotFoundException: Unable to find an entry point named 'TaskDialogIndirect' in DLL 'comctl32.dll'](https://github.com/ookii-dialogs-repros/repro-wpf-net5-comctl32-entrypointnotfoundexception) 126 | - [Calls to comctl32.dll succeed in .NET 4.8, but fail in .NET 5 with System.EntryPointNotFoundException](https://github.com/dotnet/wpf/issues/3815) 127 | 128 | ## Release History 129 | 130 | Click on the [Releases](https://github.com/ookii-dialogs/ookii-dialogs-wpf/releases) tab on GitHub. 131 | 132 | --- 133 | 134 | _Copyright © 2009-2021 Ookii Dialogs Contributors - Provided under the [BSD 3-Clause "New" or "Revised" License](LICENSE)._ 135 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security contact information 2 | 3 | To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. 4 | -------------------------------------------------------------------------------- /assets/ookii-dialogs-deprecated-nuget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/assets/ookii-dialogs-deprecated-nuget.png -------------------------------------------------------------------------------- /assets/ookii-dialogs-wpf-nuget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/assets/ookii-dialogs-wpf-nuget.png -------------------------------------------------------------------------------- /assets/ookii-dialogs.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/assets/ookii-dialogs.snk -------------------------------------------------------------------------------- /assets/sample-credential-dialog-win10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/assets/sample-credential-dialog-win10.png -------------------------------------------------------------------------------- /assets/sample-folderbrowser-dialog-win10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/assets/sample-folderbrowser-dialog-win10.png -------------------------------------------------------------------------------- /assets/sample-progress-dialog-win10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/assets/sample-progress-dialog-win10.png -------------------------------------------------------------------------------- /assets/sample-task-dialog-command-links-win10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/assets/sample-task-dialog-command-links-win10.png -------------------------------------------------------------------------------- /assets/sample-task-dialog-win10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/assets/sample-task-dialog-win10.png -------------------------------------------------------------------------------- /build.cake: -------------------------------------------------------------------------------- 1 | #addin "nuget:?package=Cake.MinVer&version=2.0.0" 2 | #addin "nuget:?package=Cake.Args&version=2.0.0" 3 | 4 | var target = ArgumentOrDefault("target") ?? "pack"; 5 | var buildVersion = MinVer(s => s.WithTagPrefix("v").WithDefaultPreReleasePhase("preview")); 6 | 7 | Task("clean") 8 | .Does(() => 9 | { 10 | CleanDirectories("./artifact/**"); 11 | CleanDirectories("./**/^{bin,obj}"); 12 | }); 13 | 14 | Task("restore") 15 | .IsDependentOn("clean") 16 | .Does(() => 17 | { 18 | DotNetRestore("./Ookii.Dialogs.Wpf.sln", new DotNetRestoreSettings 19 | { 20 | LockedMode = true, 21 | }); 22 | }); 23 | 24 | Task("build") 25 | .IsDependentOn("restore") 26 | .DoesForEach(new[] { "Debug", "Release" }, (configuration) => 27 | { 28 | DotNetBuild("./Ookii.Dialogs.Wpf.sln", new DotNetBuildSettings 29 | { 30 | Configuration = configuration, 31 | NoRestore = true, 32 | NoIncremental = false, 33 | MSBuildSettings = new DotNetMSBuildSettings 34 | { 35 | Version = buildVersion.Version, 36 | AssemblyVersion = buildVersion.AssemblyVersion, 37 | FileVersion = buildVersion.FileVersion, 38 | ContinuousIntegrationBuild = BuildSystem.IsLocalBuild, 39 | }, 40 | }); 41 | }); 42 | 43 | Task("test") 44 | .IsDependentOn("build") 45 | .Does(() => 46 | { 47 | var settings = new DotNetTestSettings 48 | { 49 | Configuration = "Release", 50 | NoRestore = true, 51 | NoBuild = true, 52 | }; 53 | 54 | var projectFiles = GetFiles("./test/**/*.csproj"); 55 | foreach (var file in projectFiles) 56 | { 57 | DotNetTest(file.FullPath, settings); 58 | } 59 | }); 60 | 61 | Task("pack") 62 | .IsDependentOn("test") 63 | .Does(() => 64 | { 65 | var releaseNotes = $"https://github.com/ookii-dialogs/ookii-dialogs-wpf/releases/tag/v{buildVersion.Version}"; 66 | 67 | DotNetPack("./src/Ookii.Dialogs.Wpf/Ookii.Dialogs.Wpf.csproj", new DotNetPackSettings 68 | { 69 | Configuration = "Release", 70 | NoRestore = true, 71 | NoBuild = true, 72 | IncludeSymbols = true, 73 | IncludeSource = true, 74 | OutputDirectory = "./artifact/nuget", 75 | MSBuildSettings = new DotNetMSBuildSettings 76 | { 77 | Version = buildVersion.Version, 78 | PackageReleaseNotes = releaseNotes, 79 | }, 80 | }); 81 | 82 | DotNetPack("./src/Ookii.Dialogs/Ookii.Dialogs.csproj", new DotNetPackSettings 83 | { 84 | Configuration = "Release", 85 | NoRestore = true, 86 | NoBuild = true, 87 | IncludeSymbols = false, 88 | IncludeSource = false, 89 | OutputDirectory = "./artifact/nuget", 90 | MSBuildSettings = new DotNetMSBuildSettings 91 | { 92 | Version = buildVersion.Version, 93 | PackageReleaseNotes = releaseNotes, 94 | }, 95 | }); 96 | }); 97 | 98 | Task("push") 99 | .IsDependentOn("pack") 100 | .Does(context => 101 | { 102 | var url = context.EnvironmentVariable("NUGET_URL"); 103 | if (string.IsNullOrWhiteSpace(url)) 104 | { 105 | context.Information("No NuGet URL specified. Skipping publishing of NuGet packages"); 106 | return; 107 | } 108 | 109 | var apiKey = context.EnvironmentVariable("NUGET_API_KEY"); 110 | if (string.IsNullOrWhiteSpace(apiKey)) 111 | { 112 | context.Information("No NuGet API key specified. Skipping publishing of NuGet packages"); 113 | return; 114 | } 115 | 116 | var nugetPushSettings = new DotNetNuGetPushSettings 117 | { 118 | Source = url, 119 | ApiKey = apiKey, 120 | }; 121 | 122 | foreach (var nugetPackageFile in GetFiles("./artifact/nuget/*.nupkg")) 123 | { 124 | DotNetNuGetPush(nugetPackageFile.FullPath, nugetPushSettings); 125 | } 126 | }); 127 | 128 | RunTarget(target); 129 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo on 2 | @cd %~dp0 3 | 4 | set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 5 | set DOTNET_CLI_TELEMETRY_OPTOUT=1 6 | set DOTNET_NOLOGO=1 7 | 8 | dotnet tool restore 9 | @if %ERRORLEVEL% neq 0 goto :eof 10 | 11 | dotnet cake %* 12 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = 'Stop' 2 | 3 | Set-Location -LiteralPath $PSScriptRoot 4 | 5 | $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1' 6 | $env:DOTNET_CLI_TELEMETRY_OPTOUT = '1' 7 | $env:DOTNET_NOLOGO = '1' 8 | 9 | dotnet tool restore 10 | if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } 11 | 12 | dotnet cake @args 13 | if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } 14 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euox pipefail 3 | 4 | cd "$(dirname "${BASH_SOURCE[0]}")" 5 | 6 | export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 7 | export DOTNET_CLI_TELEMETRY_OPTOUT=1 8 | export DOTNET_NOLOGO=1 9 | 10 | dotnet tool restore 11 | 12 | dotnet cake "$@" 13 | -------------------------------------------------------------------------------- /cake.config: -------------------------------------------------------------------------------- 1 | [Nuget] 2 | Source=https://api.nuget.org/v3/index.json 3 | UseInProcessClient=true 4 | LoadDependencies=false 5 | 6 | [Paths] 7 | Tools=./.cake 8 | Addins=./.cake/addins 9 | Modules=./.cake/modules 10 | 11 | [Settings] 12 | SkipVerification=false 13 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "allowPrerelease": false, 4 | "version": "6.0.100", 5 | "rollForward": "latestFeature" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | using System.Windows; 16 | 17 | namespace Ookii.Dialogs.Wpf.Sample 18 | { 19 | /// 20 | /// Interaction logic for App.xaml 21 | /// 22 | public partial class App : Application 23 | { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Task Dialog 15 | Task Dialog with command links 16 | Progress Dialog 17 | Credential Dialog 18 | Vista-style Folder Browser Dialog 19 | Vista-style Folder Browser Dialog (Select Multiple) 20 | Vista-style Open File Dialog 21 | Vista-style Save File Dialog 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/Ookii.Dialogs.Wpf.Sample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0-windows;net5.0-windows;netcoreapp3.1;net462 5 | WinExe 6 | true 7 | true 8 | Ookii.Dialogs.Wpf.Sample 9 | 10 | Ookii.Dialogs.Wpf.Sample 11 | ookii.ico 12 | en 13 | app.manifest 14 | 15 | true 16 | ../../assets/ookii-dialogs.snk 17 | true 18 | 19 | $(NoWarn);NU5048 20 | true 21 | 22 | 23 | 24 | 25 | true 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Ookii.Dialogs.Wpf.Sample.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Ookii.Dialogs.Wpf.Sample.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Ookii.Dialogs.Wpf.Sample.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 58 | 59 | 60 | 61 | 62 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /sample/Ookii.Dialogs.Wpf.Sample/ookii.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/sample/Ookii.Dialogs.Wpf.Sample/ookii.ico -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | # SYSLIB0003: Type or member is obsolete 3 | dotnet_diagnostic.SYSLIB0003.severity = none 4 | 5 | # SYSLIB0004: Type or member is obsolete 6 | dotnet_diagnostic.SYSLIB0004.severity = none 7 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/AnimationResource.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | using System.IO; 22 | 23 | namespace Ookii.Dialogs.Wpf 24 | { 25 | /// 26 | /// Represents an animation for the loaded from a Win32 resource. 27 | /// 28 | /// 29 | public sealed class AnimationResource 30 | { 31 | /// 32 | /// Initializes a new instance of the class. 33 | /// 34 | /// The file containing the animation resource. 35 | /// The resource ID of the animation resource. 36 | /// is . 37 | public AnimationResource(string resourceFile, int resourceId) 38 | { 39 | if( resourceFile == null ) 40 | throw new ArgumentNullException("resourceFile"); 41 | 42 | ResourceFile = resourceFile; 43 | ResourceId = resourceId; 44 | } 45 | 46 | /// 47 | /// Gets the name of the file containing the animation resource. 48 | /// 49 | /// 50 | /// The name of the file containing the animation resource. This is typically a DLL or EXE file. 51 | /// 52 | public string ResourceFile { get; private set; } 53 | 54 | /// 55 | /// Gets the ID of the animation resource. 56 | /// 57 | /// 58 | /// The ID of the animation resource. 59 | /// 60 | public int ResourceId { get; private set; } 61 | 62 | /// 63 | /// Gets a default animation from shell32.dll. 64 | /// 65 | /// The animation to get. 66 | /// An instance of the class representing the specified animation. 67 | /// The parameter was not a value defined in the 68 | /// enumeration. 69 | public static AnimationResource GetShellAnimation(ShellAnimation animation) 70 | { 71 | if( !Enum.IsDefined(typeof(ShellAnimation), animation) ) 72 | throw new ArgumentOutOfRangeException("animation"); 73 | 74 | return new AnimationResource("shell32.dll", (int)animation); 75 | } 76 | 77 | internal FreeLibrarySafeHandle LoadLibrary() 78 | { 79 | var handle = NativeMethods.LoadLibraryEx(ResourceFile, default, Windows.Win32.System.LibraryLoader.LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE); 80 | if( handle.IsInvalid ) 81 | { 82 | int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); 83 | if( error == NativeMethods.ErrorFileNotFound ) 84 | throw new FileNotFoundException(string.Format(System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.FileNotFoundFormat, ResourceFile)); 85 | else 86 | throw new System.ComponentModel.Win32Exception(error); 87 | } 88 | 89 | return handle; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ButtonType.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | /// 24 | /// Represents the type of a task dialog button. 25 | /// 26 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1027:MarkEnumsWithFlags")] 27 | public enum ButtonType 28 | { 29 | /// 30 | /// The button is a custom button. 31 | /// 32 | Custom = 0, 33 | /// 34 | /// The button is the common OK button. 35 | /// 36 | Ok = 1, 37 | /// 38 | /// The button is the common Yes button. 39 | /// 40 | Yes = 6, 41 | /// 42 | /// The button is the common No button. 43 | /// 44 | No = 7, 45 | /// 46 | /// The button is the common Cancel button. 47 | /// 48 | Cancel = 2, 49 | /// 50 | /// The button is the common Retry button. 51 | /// 52 | Retry = 4, 53 | /// 54 | /// The button is the common Close button. 55 | /// 56 | Close = 8 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ComCtlv6ActivationContext.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.IO; 19 | using System.Runtime.InteropServices; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | sealed class ComCtlv6ActivationContext : IDisposable 24 | { 25 | // Private data 26 | private nuint _cookie; 27 | private static ACTCTXW _enableThemingActivationContext; 28 | private static SafeFileHandle _activationContext; 29 | private static bool _contextCreationSucceeded; 30 | private static readonly object _contextCreationLock = new object(); 31 | 32 | public ComCtlv6ActivationContext(bool enable) 33 | { 34 | if( enable && NativeMethods.IsWindowsXPOrLater ) 35 | { 36 | if( EnsureActivateContextCreated() ) 37 | { 38 | if( !NativeMethods.ActivateActCtx(_activationContext, out _cookie) ) 39 | { 40 | // Be sure cookie always zero if activation failed 41 | _cookie = 0; 42 | } 43 | } 44 | } 45 | } 46 | 47 | ~ComCtlv6ActivationContext() 48 | { 49 | Dispose(false); 50 | } 51 | 52 | public void Dispose() 53 | { 54 | Dispose(true); 55 | GC.SuppressFinalize(this); 56 | } 57 | 58 | private void Dispose(bool disposing) 59 | { 60 | if( _cookie != 0 ) 61 | { 62 | if( NativeMethods.DeactivateActCtx(0, _cookie) ) 63 | { 64 | // deactivation succeeded... 65 | _cookie = 0; 66 | } 67 | } 68 | } 69 | 70 | private static bool EnsureActivateContextCreated() 71 | { 72 | lock (_contextCreationLock) 73 | { 74 | if (_contextCreationSucceeded) 75 | { 76 | return _contextCreationSucceeded; 77 | } 78 | 79 | const string manifestResourceName = "Ookii.Dialogs.XPThemes.manifest"; 80 | string manifestTempFilePath; 81 | 82 | using (var manifest = typeof(ComCtlv6ActivationContext).Assembly.GetManifestResourceStream(manifestResourceName)) 83 | { 84 | if (manifest is null) 85 | { 86 | throw new InvalidOperationException($"Unable to retrieve {manifestResourceName} embedded resource"); 87 | } 88 | 89 | manifestTempFilePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); 90 | 91 | using (var tempFileStream = new FileStream(manifestTempFilePath, FileMode.CreateNew, FileAccess.ReadWrite, 92 | FileShare.Delete | FileShare.ReadWrite)) 93 | { 94 | manifest.CopyTo(tempFileStream); 95 | } 96 | } 97 | 98 | unsafe 99 | { 100 | fixed (char* szManifestTempFilePath = manifestTempFilePath) 101 | { 102 | _enableThemingActivationContext = new ACTCTXW 103 | { 104 | cbSize = (uint)Marshal.SizeOf(typeof(ACTCTXW)), 105 | lpSource = szManifestTempFilePath, 106 | }; 107 | } 108 | } 109 | 110 | // Note this will fail gracefully if file specified 111 | // by manifestFilePath doesn't exist. 112 | _activationContext = NativeMethods.CreateActCtx(_enableThemingActivationContext); 113 | _contextCreationSucceeded = !_activationContext.IsInvalid; 114 | 115 | try 116 | { 117 | File.Delete(manifestTempFilePath); 118 | } 119 | catch (Exception) 120 | { 121 | // We tried to be tidy but something blocked us :( 122 | } 123 | 124 | // If we return false, we'll try again on the next call into 125 | // EnsureActivateContextCreated(), which is fine. 126 | return _contextCreationSucceeded; 127 | } 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/CredentialDialog.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/src/Ookii.Dialogs.Wpf/CredentialDialog.bmp -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/CredentialDialog.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Ookii.Dialogs.Wpf 2 | { 3 | partial class CredentialDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// if managed resources should be disposed; otherwise, . 14 | protected override void Dispose(bool disposing) 15 | { 16 | try 17 | { 18 | if( disposing && (components != null) ) 19 | { 20 | components.Dispose(); 21 | } 22 | } 23 | finally 24 | { 25 | base.Dispose(disposing); 26 | } 27 | } 28 | 29 | #region Component Designer generated code 30 | 31 | /// 32 | /// Required method for Designer support - do not modify 33 | /// the contents of this method with the code editor. 34 | /// 35 | private void InitializeComponent() 36 | { 37 | components = new System.ComponentModel.Container(); 38 | } 39 | 40 | #endregion 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/CredentialException.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.Security.Permissions; 21 | 22 | namespace Ookii.Dialogs.Wpf 23 | { 24 | /// 25 | /// The exception that is thrown when an error occurs getting credentials. 26 | /// 27 | /// 28 | [Serializable()] 29 | public class CredentialException : System.ComponentModel.Win32Exception 30 | { 31 | /// 32 | /// Initializes a new instance of the class. 33 | /// 34 | [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 35 | public CredentialException() 36 | : base(Properties.Resources.CredentialError) 37 | { 38 | } 39 | 40 | /// 41 | /// Initializes a new instance of the class with the specified error. 42 | /// 43 | /// The Win32 error code associated with this exception. 44 | [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 45 | public CredentialException(int error) 46 | : base(error) 47 | { 48 | } 49 | 50 | /// 51 | /// Initializes a new instance of the class with a specified error message. 52 | /// 53 | /// The message that describes the error. 54 | [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 55 | public CredentialException(string message) 56 | : base(message) 57 | { 58 | } 59 | 60 | /// 61 | /// Initializes a new instance of the class with the specified error and the specified detailed description. 62 | /// 63 | /// The Win32 error code associated with this exception. 64 | /// A detailed description of the error. 65 | [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 66 | public CredentialException(int error, string message) 67 | : base(error, message) 68 | { 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. 73 | /// 74 | /// The error message that explains the reason for the exception. 75 | /// A reference to the inner exception that is the cause of the current exception. 76 | [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 77 | public CredentialException(string message, Exception innerException) 78 | : base(message, innerException) 79 | { 80 | } 81 | 82 | /// 83 | /// Initializes a new instance of the class with serialized data. 84 | /// 85 | /// The that holds the serialized object data about the exception being thrown. 86 | /// The that contains contextual information about the source or destination. 87 | [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 88 | protected CredentialException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) 89 | : base(info, context) 90 | { 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/DownlevelTextMode.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace Ookii.Dialogs.Wpf 23 | { 24 | /// 25 | /// An enumeration that displays how the text in the and 26 | /// properties is displayed on a credential dialog in Windows XP. 27 | /// 28 | /// 29 | /// 30 | /// Windows XP does not support the distinct visual style of the main instruction, so there is no visual difference between the 31 | /// text of the and properties. Depending 32 | /// on the scenario, you may wish to hide either the main instruction or the content text. 33 | /// 34 | /// 35 | public enum DownlevelTextMode 36 | { 37 | /// 38 | /// The text of the and properties is 39 | /// concatenated together, separated by an empty line. 40 | /// 41 | MainInstructionAndContent, 42 | /// 43 | /// Only the text of the property is shown. 44 | /// 45 | MainInstructionOnly, 46 | /// 47 | /// Only the text of the property is shown. 48 | /// 49 | ContentOnly 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ExpandButtonClickedEventArgs.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | /// 24 | /// Provides data for the event. 25 | /// 26 | /// 27 | public class ExpandButtonClickedEventArgs : EventArgs 28 | { 29 | private bool _expanded; 30 | 31 | /// 32 | /// Initializes a new instance of the class with the specified expanded state. 33 | /// 34 | /// if the the expanded content on the dialog is shown; otherwise, . 35 | public ExpandButtonClickedEventArgs(bool expanded) 36 | { 37 | _expanded = expanded; 38 | } 39 | 40 | /// 41 | /// Gets a value that indicates if the expanded content on the dialog is shown. 42 | /// 43 | /// if the expanded content on the dialog is shown; otherwise, . 44 | public bool Expanded 45 | { 46 | get { return _expanded; } 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | // 6 | // To add a suppression to this file, right-click the message in the 7 | // Error List, point to "Suppress Message(s)", and click 8 | // "In Project Suppression File". 9 | // You do not need to add suppressions to this file manually. 10 | 11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Scope = "member", Target = "Ookii.Dialogs.Wpf.ComCtlv6ActivationContext.#_cookie")] 12 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "disposing", Scope = "member", Target = "Ookii.Dialogs.Wpf.ComCtlv6ActivationContext.#Dispose(System.Boolean)")] 13 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Scope = "member", Target = "Ookii.Dialogs.Wpf.VistaFileDialog.#.ctor()")] 14 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multiselect", Scope = "member", Target = "Ookii.Dialogs.Wpf.VistaOpenFileDialog.#Multiselect")] 15 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/HyperlinkClickedEventArgs.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | /// 24 | /// Class that provides data for the event. 25 | /// 26 | /// 27 | public class HyperlinkClickedEventArgs : EventArgs 28 | { 29 | private string _href; 30 | 31 | /// 32 | /// Creates a new instance of the class with the specified URL. 33 | /// 34 | /// The URL of the hyperlink. 35 | public HyperlinkClickedEventArgs(string href) 36 | { 37 | _href = href; 38 | } 39 | 40 | /// 41 | /// Gets the URL of the hyperlink that was clicked. 42 | /// 43 | /// 44 | /// The value of the href attribute of the hyperlink. 45 | /// 46 | public string Href 47 | { 48 | get { return _href; } 49 | } 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Interop/COMGuids.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | namespace Ookii.Dialogs.Wpf.Interop 18 | { 19 | internal static class IIDGuid 20 | { 21 | internal const string IFileOpenDialog = "d57c7288-d4ad-4768-be02-9d969532d960"; 22 | internal const string IFileSaveDialog = "84bccd23-5fde-4cdb-aea4-af64b83d78ab"; 23 | internal const string IKnownFolderManager = "44BEAAEC-24F4-4E90-B3F0-23D258FBB146"; 24 | internal const string IProgressDialog = "EBBC7C04-315E-11d2-B62F-006097DF5BD4"; 25 | } 26 | 27 | internal static class CLSIDGuid 28 | { 29 | internal const string FileOpenDialog = "DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7"; 30 | internal const string FileSaveDialog = "C0B4E2F3-BA21-4773-8DBA-335EC946EB8B"; 31 | internal const string KnownFolderManager = "4df0c730-df9d-4ae3-9153-aa6b82e9795a"; 32 | internal const string ProgressDialog = "F8383852-FCD3-11d1-A6B9-006097DF5BD4"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Interop/ComDlgResources.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | namespace Ookii.Dialogs.Wpf.Interop 18 | { 19 | static class ComDlgResources 20 | { 21 | public enum ComDlgResourceId 22 | { 23 | OpenButton = 370, 24 | Open = 384, 25 | FileNotFound = 391, 26 | CreatePrompt = 402, 27 | ReadOnly = 427, 28 | ConfirmSaveAs = 435 29 | } 30 | 31 | private static Win32Resources _resources = new Win32Resources("comdlg32.dll"); 32 | 33 | public static string LoadString(ComDlgResourceId id) 34 | { 35 | return _resources.LoadString((uint)id); 36 | } 37 | 38 | public static string FormatString(ComDlgResourceId id, params string[] args) 39 | { 40 | return _resources.FormatString((uint)id, args); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Interop/IProgressDialog.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Runtime.InteropServices; 19 | 20 | namespace Ookii.Dialogs.Wpf.Interop 21 | { 22 | [ComImport] 23 | [Guid(CLSIDGuid.ProgressDialog)] 24 | internal class ProgressDialogRCW 25 | { 26 | } 27 | 28 | [ComImport, 29 | Guid(IIDGuid.IProgressDialog), 30 | CoClass(typeof(ProgressDialogRCW))] 31 | internal interface ProgressDialog : IProgressDialog 32 | { 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Interop/ShellWrapperDefinitions.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.Runtime.InteropServices; 21 | 22 | namespace Ookii.Dialogs.Wpf.Interop 23 | { 24 | // Dummy base interface for CommonFileDialog coclasses 25 | internal interface NativeCommonFileDialog 26 | { } 27 | 28 | // --------------------------------------------------------- 29 | // Coclass interfaces - designed to "look like" the object 30 | // in the API, so that the 'new' operator can be used in a 31 | // straightforward way. Behind the scenes, the C# compiler 32 | // morphs all 'new CoClass()' calls to 'new CoClassWrapper()' 33 | [ComImport, 34 | Guid(IIDGuid.IFileOpenDialog), 35 | CoClass(typeof(FileOpenDialogRCW))] 36 | internal interface NativeFileOpenDialog : IFileOpenDialog 37 | { 38 | } 39 | 40 | [ComImport, 41 | Guid(IIDGuid.IFileSaveDialog), 42 | CoClass(typeof(FileSaveDialogRCW))] 43 | internal interface NativeFileSaveDialog : IFileSaveDialog 44 | { 45 | } 46 | 47 | [ComImport, 48 | Guid(IIDGuid.IKnownFolderManager), 49 | CoClass(typeof(KnownFolderManagerRCW))] 50 | internal interface KnownFolderManager : IKnownFolderManager 51 | { 52 | } 53 | 54 | // --------------------------------------------------- 55 | // .NET classes representing runtime callable wrappers 56 | [ComImport, 57 | ClassInterface(ClassInterfaceType.None), 58 | TypeLibType(TypeLibTypeFlags.FCanCreate), 59 | Guid(CLSIDGuid.FileOpenDialog)] 60 | internal class FileOpenDialogRCW 61 | { 62 | } 63 | 64 | [ComImport, 65 | ClassInterface(ClassInterfaceType.None), 66 | TypeLibType(TypeLibTypeFlags.FCanCreate), 67 | Guid(CLSIDGuid.FileSaveDialog)] 68 | internal class FileSaveDialogRCW 69 | { 70 | } 71 | 72 | [ComImport, 73 | ClassInterface(ClassInterfaceType.None), 74 | TypeLibType(TypeLibTypeFlags.FCanCreate), 75 | Guid(CLSIDGuid.KnownFolderManager)] 76 | internal class KnownFolderManagerRCW 77 | { 78 | } 79 | 80 | 81 | // TODO: make these available (we'll need them when passing in 82 | // shell items to the CFD API 83 | //[ComImport, 84 | //Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"), 85 | //CoClass(typeof(ShellItemClass))] 86 | //internal interface ShellItem : IShellItem 87 | //{ 88 | //} 89 | 90 | //// NOTE: This GUID is for CLSID_ShellItem, which 91 | //// actually implements IShellItem2, which has lots of 92 | //// stuff we don't need 93 | //[ComImport, 94 | //ClassInterface(ClassInterfaceType.None), 95 | //TypeLibType(TypeLibTypeFlags.FCanCreate)] 96 | //internal class ShellItemClass 97 | //{ 98 | //} 99 | } 100 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Interop/Win32Resources.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Runtime.InteropServices; 20 | using System.Text; 21 | using Windows.Win32; 22 | using Windows.Win32.System.Diagnostics.Debug; 23 | using Windows.Win32.System.LibraryLoader; 24 | using System.Runtime.CompilerServices; 25 | 26 | namespace Ookii.Dialogs.Wpf.Interop 27 | { 28 | class Win32Resources : IDisposable 29 | { 30 | private SafeHandle _moduleHandle; 31 | private const int _bufferSize = 500; 32 | 33 | public Win32Resources(string module) 34 | { 35 | _moduleHandle = NativeMethods.LoadLibraryEx(module, default, LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE); 36 | if (_moduleHandle.IsInvalid) 37 | throw new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); 38 | } 39 | 40 | public unsafe string LoadString(uint id) 41 | { 42 | CheckDisposed(); 43 | 44 | Span buffer = stackalloc char[_bufferSize]; 45 | fixed (char* pBuffer = buffer) 46 | { 47 | if (NativeMethods.LoadString(_moduleHandle, id, pBuffer, _bufferSize + 1) == 0) 48 | throw new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); 49 | } 50 | return buffer.ToString(); 51 | } 52 | 53 | public unsafe string FormatString(uint id, params string[] args) 54 | { 55 | CheckDisposed(); 56 | 57 | PWSTR buffer = new(); 58 | string source = LoadString(id); 59 | 60 | // For some reason FORMAT_MESSAGE_FROM_HMODULE doesn't work so we use this way. 61 | FORMAT_MESSAGE_OPTIONS flags = FORMAT_MESSAGE_OPTIONS.FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_OPTIONS.FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_OPTIONS.FORMAT_MESSAGE_FROM_STRING; 62 | 63 | IntPtr sourcePtr = System.Runtime.InteropServices.Marshal.StringToHGlobalAuto(source); 64 | try 65 | { 66 | fixed (char* pargs = args[0]) 67 | { 68 | if (NativeMethods.FormatMessage(flags, (void*)sourcePtr, id, 0, (PWSTR)Unsafe.AsPointer(ref buffer), 0, (sbyte**)&pargs) == 0) 69 | throw new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); 70 | } 71 | } 72 | finally 73 | { 74 | System.Runtime.InteropServices.Marshal.FreeHGlobal(sourcePtr); 75 | } 76 | 77 | string result = buffer.ToString(); 78 | // FreeHGlobal calls LocalFree 79 | System.Runtime.InteropServices.Marshal.FreeHGlobal((IntPtr)Unsafe.AsPointer(ref buffer)); 80 | 81 | return result; 82 | } 83 | 84 | protected virtual void Dispose(bool disposing) 85 | { 86 | if (disposing) 87 | _moduleHandle.Dispose(); 88 | } 89 | 90 | private void CheckDisposed() 91 | { 92 | if (_moduleHandle.IsClosed) 93 | { 94 | throw new ObjectDisposedException("Win32Resources"); 95 | } 96 | } 97 | 98 | #region IDisposable Members 99 | 100 | public void Dispose() 101 | { 102 | Dispose(true); 103 | GC.SuppressFinalize(this); 104 | } 105 | 106 | #endregion 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Runtime.InteropServices; 19 | using System.Runtime.CompilerServices; 20 | 21 | namespace Windows.Win32 22 | { 23 | static partial class NativeMethods 24 | { 25 | public const int ErrorFileNotFound = 2; 26 | 27 | public static bool IsWindowsVistaOrLater 28 | { 29 | get 30 | { 31 | return Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version >= new Version(6, 0, 6000); 32 | } 33 | } 34 | 35 | public static bool IsWindowsXPOrLater 36 | { 37 | get 38 | { 39 | return Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version >= new Version(5, 1, 2600); 40 | } 41 | } 42 | 43 | public static IShellItem CreateItemFromParsingName(string path) 44 | { 45 | // https://github.com/microsoft/CsWin32/issues/434#issuecomment-956966139 46 | var guid = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"); // IID_IShellItem 47 | var hr = SHCreateItemFromParsingName(path, default, guid/*typeof(IShellItem).GUID*/, out var o); 48 | if (hr != 0) 49 | throw new global::System.ComponentModel.Win32Exception(hr); 50 | 51 | IShellItem shellItem = (IShellItem)o; 52 | return shellItem; 53 | } 54 | 55 | internal const int CREDUI_MAX_PASSWORD_LENGTH = 256; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/NativeMethods.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://aka.ms/CsWin32.schema.json", 3 | "emitSingleFile": false, 4 | "className": "NativeMethods", 5 | "comInterop": { 6 | "preserveSigMethods": [ 7 | "IFileDialog.Show", 8 | "IFileDialogEvents.OnFileOk", 9 | "IFileDialogEvents.OnFolderChanging" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/NativeMethods.txt: -------------------------------------------------------------------------------- 1 | ACTCTXW 2 | ActivateActCtx 3 | BFFM_ENABLEOK 4 | BFFM_INITIALIZED 5 | BFFM_IUNKNOWN 6 | BFFM_SELCHANGED 7 | BFFM_SETSELECTION 8 | BFFM_VALIDATEFAILED 9 | BIF_NEWDIALOGSTYLE 10 | BIF_NONEWFOLDERBUTTON 11 | BIF_RETURNONLYFSDIRS 12 | COMDLG_FILTERSPEC 13 | CreateActCtx 14 | CredDelete 15 | CredFree 16 | CredPackAuthenticationBuffer 17 | CredRead 18 | CREDUI_FLAGS 19 | CREDUI_INFOW 20 | CREDUI_MAX_USERNAME_LENGTH 21 | CredUIPromptForCredentials 22 | CredUIPromptForWindowsCredentials 23 | CredUnPackAuthenticationBuffer 24 | CredWrite 25 | DeactivateActCtx 26 | EnableWindow 27 | FDE_SHAREVIOLATION_RESPONSE 28 | FILEOPENDIALOGOPTIONS 29 | FormatMessage 30 | GetActiveWindow 31 | GetCurrentThreadId 32 | GetWindowThreadProcessId 33 | HRESULT_FROM_WIN32 34 | ICON_SMALL 35 | IFileDialogControlEvents 36 | IFileOpenDialog 37 | IFileSaveDialog 38 | IKnownFolderManager 39 | IMalloc 40 | IProgressDialog 41 | IShellItem 42 | LoadLibraryEx 43 | LoadString 44 | MAX_PATH 45 | PathParseIconLocation 46 | PDTIMER_RESUME 47 | PROGDLG_AUTOTIME 48 | PROGDLG_MARQUEEPROGRESS 49 | PROGDLG_MODAL 50 | PROGDLG_NOCANCEL 51 | PROGDLG_NOMINIMIZE 52 | PROGDLG_NOPROGRESSBAR 53 | PROGDLG_NORMAL 54 | PROGDLG_NOTIME 55 | ReleaseActCtx 56 | S_FALSE 57 | S_OK 58 | SendMessage 59 | SHBrowseForFolder 60 | SHCreateItemFromParsingName 61 | SHGetMalloc 62 | SHGetPathFromIDList 63 | SHGetSpecialFolderLocation 64 | SIGDN 65 | TASKDIALOG_BUTTON 66 | TASKDIALOG_ELEMENTS 67 | TASKDIALOG_MESSAGES 68 | TASKDIALOG_NOTIFICATIONS 69 | TaskDialogIndirect 70 | WIN32_ERROR 71 | WM_GETICON 72 | WM_SETICON 73 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Ookii.Dialogs.Wpf.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0-windows;net5.0-windows;netcoreapp3.1;net462 5 | true 6 | true 7 | Ookii.Dialogs.Wpf 8 | 9 | Ookii.Dialogs.Wpf 10 | 3.0.0.0 11 | true 12 | true 13 | true 14 | 15 | true 16 | portable 17 | true 18 | true 19 | snupkg 20 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb 21 | 22 | true 23 | ../../assets/ookii-dialogs.snk 24 | true 25 | 26 | $(NoWarn);NU5048 27 | true 28 | 29 | 30 | true 31 | true 32 | true 33 | 10 34 | 35 | 36 | 37 | 3.3 38 | Ookii.Dialogs.Wpf 39 | 0.0.1-local 40 | Ookii Dialogs Contributors 41 | Ookii.Dialogs.Wpf is a class library for WPF applications providing several common dialogs. Included are classes for task dialogs, credential dialogs, progress dialogs, and common file dialogs. 42 | Copyright (c) 2009-2021 Ookii Dialogs Contributors 43 | ookii;dialogs;wpf;windows-presentation-foundation;progress-dialog;task-dialog;credential-dialog;common-file-dialog 44 | BSD-3-Clause 45 | images\icon.png 46 | https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/master/assets/ookii-dialogs-wpf-nuget.png 47 | https://github.com/ookii-dialogs/ookii-dialogs-wpf 48 | https://github.com/ookii-dialogs/ookii-dialogs-wpf/releases 49 | git 50 | https://github.com/ookii-dialogs/ookii-dialogs-wpf.git 51 | 52 | 53 | 54 | $(DefineConstants);NETFX 55 | 56 | 57 | 58 | $(DefineConstants);NETCORE31 59 | 60 | 61 | 62 | $(DefineConstants);NET5 63 | 64 | 65 | 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | Ookii.Dialogs.XPThemes.manifest 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | CredentialDialog.cs 132 | 133 | 134 | 135 | ProgressDialog.cs 136 | 137 | 138 | True 139 | True 140 | Resources.resx 141 | 142 | 143 | 144 | TaskDialog.cs 145 | 146 | 147 | 148 | 149 | TaskDialogItem.cs 150 | 151 | 152 | 153 | 154 | 155 | 156 | ProgressDialog.cs 157 | 158 | 159 | ResXFileCodeGenerator 160 | Resources.Designer.cs 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ProgressBarState.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | /// 24 | /// Represents the state of the progress bar on the task dialog. 25 | /// 26 | public enum ProgressBarState 27 | { 28 | /// 29 | /// Normal state. 30 | /// 31 | Normal, 32 | /// 33 | /// Error state 34 | /// 35 | Error, 36 | /// 37 | /// Paused state 38 | /// 39 | Paused 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ProgressBarStyle.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | /// 24 | /// Indicates the type of progress on a task dialog. 25 | /// 26 | public enum ProgressBarStyle 27 | { 28 | /// 29 | /// No progress bar is displayed on the dialog. 30 | /// 31 | None, 32 | /// 33 | /// A regular progress bar is displayed on the dialog. 34 | /// 35 | ProgressBar, 36 | /// 37 | /// A marquee progress bar is displayed on the dialog. Use this value for operations 38 | /// that cannot report concrete progress information. 39 | /// 40 | MarqueeProgressBar 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ProgressDialog.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/src/Ookii.Dialogs.Wpf/ProgressDialog.bmp -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ProgressDialog.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Ookii.Dialogs.Wpf 2 | { 3 | partial class ProgressDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// if managed resources should be disposed; otherwise, . 14 | protected override void Dispose(bool disposing) 15 | { 16 | try 17 | { 18 | if( disposing ) 19 | { 20 | if( components != null ) 21 | components.Dispose(); 22 | if( _currentAnimationModuleHandle != null ) 23 | { 24 | _currentAnimationModuleHandle.Dispose(); 25 | _currentAnimationModuleHandle = null; 26 | } 27 | 28 | var cancellationTokenSource = _cancellationTokenSource; 29 | if (!(cancellationTokenSource is null)) 30 | { 31 | cancellationTokenSource.Dispose(); 32 | _cancellationTokenSource = null; 33 | } 34 | } 35 | } 36 | finally 37 | { 38 | base.Dispose(disposing); 39 | } 40 | } 41 | 42 | #region Component Designer generated code 43 | 44 | /// 45 | /// Required method for Designer support - do not modify 46 | /// the contents of this method with the code editor. 47 | /// 48 | private void InitializeComponent() 49 | { 50 | this._backgroundWorker = new System.ComponentModel.BackgroundWorker(); 51 | // 52 | // _backgroundWorker 53 | // 54 | this._backgroundWorker.WorkerReportsProgress = true; 55 | this._backgroundWorker.WorkerSupportsCancellation = true; 56 | this._backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this._backgroundWorker_DoWork); 57 | this._backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this._backgroundWorker_RunWorkerCompleted); 58 | this._backgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this._backgroundWorker_ProgressChanged); 59 | 60 | } 61 | 62 | #endregion 63 | 64 | private System.ComponentModel.BackgroundWorker _backgroundWorker; 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ProgressDialog.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | False 125 | 126 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ProgressDialogDoWorkEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Threading; 3 | 4 | namespace Ookii.Dialogs.Wpf 5 | { 6 | /// 7 | /// Provides data for the System.ComponentModel.BackgroundWorker.DoWork event handler. 8 | /// 9 | public class ProgressDialogDoWorkEventArgs : DoWorkEventArgs 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | /// Specifies an argument for an asynchronous operation. 15 | /// Specifies a cancellation token for an asynchronous operation. 16 | public ProgressDialogDoWorkEventArgs(object argument, CancellationToken cancellationToken) 17 | : base(argument) 18 | { 19 | CancellationToken = cancellationToken; 20 | } 21 | 22 | /// 23 | /// Gets a value that represents the CancellationToken of an asynchronous operation. 24 | /// 25 | public CancellationToken CancellationToken { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Ookii.Dialogs.Wpf.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Ookii.Dialogs.Wpf.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Unable to load the progress dialog animation: {0}. 65 | /// 66 | internal static string AnimationLoadErrorFormat { 67 | get { 68 | return ResourceManager.GetString("AnimationLoadErrorFormat", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to The credential target may not be an empty string.. 74 | /// 75 | internal static string CredentialEmptyTargetError { 76 | get { 77 | return ResourceManager.GetString("CredentialEmptyTargetError", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to An error occurred acquiring credentials.. 83 | /// 84 | internal static string CredentialError { 85 | get { 86 | return ResourceManager.GetString("CredentialError", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// Looks up a localized string similar to PromptForCredentialsWithSave has not been called or the credentials were modified after the call.. 92 | /// 93 | internal static string CredentialPromptNotCalled { 94 | get { 95 | return ResourceManager.GetString("CredentialPromptNotCalled", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// Looks up a localized string similar to The task dialog already has a non-custom button with the same type.. 101 | /// 102 | internal static string DuplicateButtonTypeError { 103 | get { 104 | return ResourceManager.GetString("DuplicateButtonTypeError", resourceCulture); 105 | } 106 | } 107 | 108 | /// 109 | /// Looks up a localized string similar to The task dialog already has an item with the same id.. 110 | /// 111 | internal static string DuplicateItemIdError { 112 | get { 113 | return ResourceManager.GetString("DuplicateItemIdError", resourceCulture); 114 | } 115 | } 116 | 117 | /// 118 | /// Looks up a localized string similar to The file "{0}" could not be found.. 119 | /// 120 | internal static string FileNotFoundFormat { 121 | get { 122 | return ResourceManager.GetString("FileNotFoundFormat", resourceCulture); 123 | } 124 | } 125 | 126 | /// 127 | /// Looks up a localized string similar to Unable to retrieve the root folder.. 128 | /// 129 | internal static string FolderBrowserDialogNoRootFolder { 130 | get { 131 | return ResourceManager.GetString("FolderBrowserDialogNoRootFolder", resourceCulture); 132 | } 133 | } 134 | 135 | /// 136 | /// Looks up a localized string similar to The current operating system does not support glass, or the Desktop Window Manager is not enabled.. 137 | /// 138 | internal static string GlassNotSupportedError { 139 | get { 140 | return ResourceManager.GetString("GlassNotSupportedError", resourceCulture); 141 | } 142 | } 143 | 144 | /// 145 | /// Looks up a localized string similar to Invalid filter string,. 146 | /// 147 | internal static string InvalidFilterString { 148 | get { 149 | return ResourceManager.GetString("InvalidFilterString", resourceCulture); 150 | } 151 | } 152 | 153 | /// 154 | /// Looks up a localized string similar to The id of a task dialog item must be higher than 0.. 155 | /// 156 | internal static string InvalidTaskDialogItemIdError { 157 | get { 158 | return ResourceManager.GetString("InvalidTaskDialogItemIdError", resourceCulture); 159 | } 160 | } 161 | 162 | /// 163 | /// Looks up a localized string similar to The item is not associated with a task dialog.. 164 | /// 165 | internal static string NoAssociatedTaskDialogError { 166 | get { 167 | return ResourceManager.GetString("NoAssociatedTaskDialogError", resourceCulture); 168 | } 169 | } 170 | 171 | /// 172 | /// Looks up a localized string similar to Cannot change the id for a standard button.. 173 | /// 174 | internal static string NonCustomTaskDialogButtonIdError { 175 | get { 176 | return ResourceManager.GetString("NonCustomTaskDialogButtonIdError", resourceCulture); 177 | } 178 | } 179 | 180 | /// 181 | /// Looks up a localized string similar to Preview. 182 | /// 183 | internal static string Preview { 184 | get { 185 | return ResourceManager.GetString("Preview", resourceCulture); 186 | } 187 | } 188 | 189 | /// 190 | /// Looks up a localized string similar to The progress dialog is not shown.. 191 | /// 192 | internal static string ProgressDialogNotRunningError { 193 | get { 194 | return ResourceManager.GetString("ProgressDialogNotRunningError", resourceCulture); 195 | } 196 | } 197 | 198 | /// 199 | /// Looks up a localized string similar to The progress dialog is already running.. 200 | /// 201 | internal static string ProgressDialogRunning { 202 | get { 203 | return ResourceManager.GetString("ProgressDialogRunning", resourceCulture); 204 | } 205 | } 206 | 207 | /// 208 | /// Looks up a localized string similar to A custom button or radio button cannot have an empty label.. 209 | /// 210 | internal static string TaskDialogEmptyButtonLabelError { 211 | get { 212 | return ResourceManager.GetString("TaskDialogEmptyButtonLabelError", resourceCulture); 213 | } 214 | } 215 | 216 | /// 217 | /// Looks up a localized string similar to Cross-thread operation not valid: Task dialog accessed from a thread other than the thread it was created on while it is visible.. 218 | /// 219 | internal static string TaskDialogIllegalCrossThreadCallError { 220 | get { 221 | return ResourceManager.GetString("TaskDialogIllegalCrossThreadCallError", resourceCulture); 222 | } 223 | } 224 | 225 | /// 226 | /// Looks up a localized string similar to The task dialog item already belongs to another task dialog.. 227 | /// 228 | internal static string TaskDialogItemHasOwnerError { 229 | get { 230 | return ResourceManager.GetString("TaskDialogItemHasOwnerError", resourceCulture); 231 | } 232 | } 233 | 234 | /// 235 | /// Looks up a localized string similar to The task dialog must have buttons.. 236 | /// 237 | internal static string TaskDialogNoButtonsError { 238 | get { 239 | return ResourceManager.GetString("TaskDialogNoButtonsError", resourceCulture); 240 | } 241 | } 242 | 243 | /// 244 | /// Looks up a localized string similar to The task dialog is not current displayed.. 245 | /// 246 | internal static string TaskDialogNotRunningError { 247 | get { 248 | return ResourceManager.GetString("TaskDialogNotRunningError", resourceCulture); 249 | } 250 | } 251 | 252 | /// 253 | /// Looks up a localized string similar to The task dialog is already being displayed.. 254 | /// 255 | internal static string TaskDialogRunningError { 256 | get { 257 | return ResourceManager.GetString("TaskDialogRunningError", resourceCulture); 258 | } 259 | } 260 | 261 | /// 262 | /// Looks up a localized string similar to The operating system does not support task dialogs.. 263 | /// 264 | internal static string TaskDialogsNotSupportedError { 265 | get { 266 | return ResourceManager.GetString("TaskDialogsNotSupportedError", resourceCulture); 267 | } 268 | } 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Unable to load the progress dialog animation: {0} 122 | 123 | 124 | The credential target may not be an empty string. 125 | 126 | 127 | An error occurred acquiring credentials. 128 | 129 | 130 | PromptForCredentialsWithSave has not been called or the credentials were modified after the call. 131 | 132 | 133 | The task dialog already has a non-custom button with the same type. 134 | 135 | 136 | The task dialog already has an item with the same id. 137 | 138 | 139 | The file "{0}" could not be found. 140 | 141 | 142 | Unable to retrieve the root folder. 143 | 144 | 145 | The current operating system does not support glass, or the Desktop Window Manager is not enabled. 146 | 147 | 148 | Invalid filter string, 149 | 150 | 151 | The id of a task dialog item must be higher than 0. 152 | 153 | 154 | The item is not associated with a task dialog. 155 | 156 | 157 | Cannot change the id for a standard button. 158 | 159 | 160 | Preview 161 | 162 | 163 | The progress dialog is not shown. 164 | 165 | 166 | The progress dialog is already running. 167 | 168 | 169 | A custom button or radio button cannot have an empty label. 170 | 171 | 172 | Cross-thread operation not valid: Task dialog accessed from a thread other than the thread it was created on while it is visible. 173 | 174 | 175 | The task dialog item already belongs to another task dialog. 176 | 177 | 178 | The task dialog must have buttons. 179 | 180 | 181 | The task dialog is not current displayed. 182 | 183 | 184 | The task dialog is already being displayed. 185 | 186 | 187 | The operating system does not support task dialogs. 188 | 189 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/Properties/XPThemes.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | Windows Forms Common Control manifest 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/ShellAnimation.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace Ookii.Dialogs.Wpf 23 | { 24 | /// 25 | /// Resource identifiers for default animations from shell32.dll. 26 | /// 27 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")] 28 | public enum ShellAnimation 29 | { 30 | /// 31 | /// An animation representing a file move. 32 | /// 33 | FileMove = 160, 34 | /// 35 | /// An animation representing a file copy. 36 | /// 37 | FileCopy = 161, 38 | /// 39 | /// An animation showing flying papers. 40 | /// 41 | FlyingPapers = 165, 42 | /// 43 | /// An animation showing a magnifying glass over a globe. 44 | /// 45 | SearchGlobe = 166, 46 | /// 47 | /// An animation representing a permament delete. 48 | /// 49 | PermanentDelete = 164, 50 | /// 51 | /// An animation representing deleting an item from the recycle bin. 52 | /// 53 | FromRecycleBinDelete = 163, 54 | /// 55 | /// An animation representing a file move to the recycle bin. 56 | /// 57 | ToRecycleBinDelete = 162, 58 | /// 59 | /// An animation representing a search spanning the local computer. 60 | /// 61 | SearchComputer = 152, 62 | /// 63 | /// An animation representing a search in a document.. 64 | /// 65 | SearchDocument = 151, 66 | /// 67 | /// An animation representing a search using a flashlight animation. 68 | /// 69 | SearchFlashlight = 150, 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/SpanExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ookii.Dialogs.Wpf 4 | { 5 | internal static class SpanExtensions 6 | { 7 | /// 8 | /// Drops '\0' character padding before converting to string. 9 | /// 10 | /// Span to convert to string. 11 | /// Resulting string. 12 | public static string ToCleanString(this Span span) => span.Slice(0, span.IndexOf('\0')).ToString(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialog.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/src/Ookii.Dialogs.Wpf/TaskDialog.bmp -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialog.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Ookii.Dialogs.Wpf 2 | { 3 | partial class TaskDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// if managed resources should be disposed; otherwise, . 14 | protected override void Dispose(bool disposing) 15 | { 16 | try 17 | { 18 | if( disposing ) 19 | { 20 | if( components != null ) 21 | { 22 | components.Dispose(); 23 | components = null; 24 | } 25 | if( _buttons != null ) 26 | { 27 | foreach( TaskDialogButton button in _buttons ) 28 | { 29 | button.Dispose(); 30 | } 31 | _buttons.Clear(); 32 | } 33 | if( _radioButtons != null ) 34 | { 35 | foreach( TaskDialogRadioButton radioButton in _radioButtons ) 36 | { 37 | radioButton.Dispose(); 38 | } 39 | _radioButtons.Clear(); 40 | } 41 | } 42 | } 43 | finally 44 | { 45 | base.Dispose(disposing); 46 | } 47 | } 48 | 49 | #region Component Designer generated code 50 | 51 | /// 52 | /// Required method for Designer support - do not modify 53 | /// the contents of this method with the code editor. 54 | /// 55 | private void InitializeComponent() 56 | { 57 | components = new System.ComponentModel.Container(); 58 | } 59 | 60 | #endregion 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogButton.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.ComponentModel; 21 | using System.Drawing.Design; 22 | 23 | namespace Ookii.Dialogs.Wpf 24 | { 25 | /// 26 | /// A button on a . 27 | /// 28 | /// 29 | public class TaskDialogButton : TaskDialogItem 30 | { 31 | private ButtonType _type; 32 | private bool _elevationRequired; 33 | private bool _default; 34 | private string _commandLinkNote; 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | public TaskDialogButton() 40 | { 41 | } 42 | 43 | /// 44 | /// Initializes a new instance of the class with the specified button type. 45 | /// 46 | /// The type of the button. 47 | public TaskDialogButton(ButtonType type) 48 | : base((int)type) 49 | { 50 | _type = type; 51 | } 52 | 53 | /// 54 | /// Initializes a new instance of the class with the specified container. 55 | /// 56 | /// The to add the to. 57 | public TaskDialogButton(IContainer container) 58 | : base(container) 59 | { 60 | } 61 | 62 | /// 63 | /// Initializes a new instance of the class with the specified text. 64 | /// 65 | /// The text of the button. 66 | public TaskDialogButton(string text) 67 | { 68 | Text = text; 69 | } 70 | 71 | /// 72 | /// Gets or sets the type of the button. 73 | /// 74 | /// 75 | /// One of the values that indicates the type of the button. The default value 76 | /// is . 77 | /// 78 | [Category("Appearance"), Description("The type of the button."), DefaultValue(ButtonType.Custom)] 79 | public ButtonType ButtonType 80 | { 81 | get { return _type; } 82 | set 83 | { 84 | if( value != ButtonType.Custom ) 85 | { 86 | CheckDuplicateButton(value, null); 87 | _type = value; 88 | base.Id = (int)value; 89 | } 90 | else 91 | { 92 | _type = value; 93 | AutoAssignId(); 94 | UpdateOwner(); 95 | } 96 | } 97 | } 98 | 99 | /// 100 | /// Gets or sets the text of the note associated with a command link button. 101 | /// 102 | /// 103 | /// The text of the note associated with a command link button. 104 | /// 105 | /// 106 | /// 107 | /// This property applies only to buttons where the property 108 | /// is . For other button types, it is ignored. 109 | /// 110 | /// 111 | /// In addition, it is used only if the property is set to 112 | /// or ; 113 | /// otherwise, it is ignored. 114 | /// 115 | /// 116 | [Localizable(true), Category("Appearance"), Description("The text of the note associated with a command link button."), DefaultValue(""), Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(UITypeEditor))] 117 | public string CommandLinkNote 118 | { 119 | get { return _commandLinkNote ?? string.Empty; } 120 | set 121 | { 122 | _commandLinkNote = value; 123 | UpdateOwner(); 124 | } 125 | } 126 | 127 | 128 | /// 129 | /// Gets or sets a value that indicates if the button is the default button on the dialog. 130 | /// 131 | /// if the button is the default button; otherwise, . 132 | /// The default value is . 133 | /// 134 | /// If no button has this property set to , the first button on the dialog will be the default button. 135 | /// 136 | [Category("Behavior"), Description("Indicates if the button is the default button on the dialog."), DefaultValue(false)] 137 | public bool Default 138 | { 139 | get { return _default; } 140 | set 141 | { 142 | _default = value; 143 | if( value && Owner != null ) 144 | { 145 | foreach( TaskDialogButton button in Owner.Buttons ) 146 | { 147 | if( button != this ) 148 | button.Default = false; 149 | } 150 | } 151 | UpdateOwner(); 152 | } 153 | } 154 | 155 | /// 156 | /// Gets or sets a value that indicates whether the Task Dialog button or command link should have a 157 | /// User Account Control (UAC) shield icon (in other words, whether the action invoked by the 158 | /// button requires elevation). 159 | /// 160 | /// 161 | /// if the button contains a UAC shield icon; otherwise, . 162 | /// 163 | /// 164 | /// Elevation is not performed by the task dialog; the code implementing the operation that results from 165 | /// the button being clicked is responsible for performing elevation if required. 166 | /// 167 | [Category("Behavior"), Description("Indicates whether the Task Dialog button or command link should have a User Account Control (UAC) shield icon (in other words, whether the action invoked by the button requires elevation)."), DefaultValue(false)] 168 | public bool ElevationRequired 169 | { 170 | get { return _elevationRequired; } 171 | set 172 | { 173 | _elevationRequired = value; 174 | if( Owner != null ) 175 | Owner.SetButtonElevationRequired(this); 176 | } 177 | } 178 | 179 | 180 | internal override int Id 181 | { 182 | get 183 | { 184 | return base.Id; 185 | } 186 | set 187 | { 188 | if( base.Id != value ) 189 | { 190 | if( _type != ButtonType.Custom ) 191 | throw new InvalidOperationException(Properties.Resources.NonCustomTaskDialogButtonIdError); 192 | base.Id = value; 193 | } 194 | } 195 | } 196 | 197 | internal override void AutoAssignId() 198 | { 199 | if( _type == ButtonType.Custom ) 200 | base.AutoAssignId(); 201 | } 202 | 203 | internal override void CheckDuplicate(TaskDialogItem itemToExclude) 204 | { 205 | CheckDuplicateButton(_type, itemToExclude); 206 | base.CheckDuplicate(itemToExclude); 207 | } 208 | 209 | internal TASKDIALOG_COMMON_BUTTON_FLAGS ButtonFlag 210 | { 211 | get 212 | { 213 | switch( _type ) 214 | { 215 | case ButtonType.Ok: 216 | return TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_OK_BUTTON; 217 | case ButtonType.Yes: 218 | return TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_YES_BUTTON; 219 | case ButtonType.No: 220 | return TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_NO_BUTTON; 221 | case ButtonType.Cancel: 222 | return TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_CANCEL_BUTTON; 223 | case ButtonType.Retry: 224 | return TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_RETRY_BUTTON; 225 | case ButtonType.Close: 226 | return TASKDIALOG_COMMON_BUTTON_FLAGS.TDCBF_CLOSE_BUTTON; 227 | default: 228 | return 0; 229 | } 230 | } 231 | } 232 | 233 | /// 234 | /// Gets the collection that items of this type are part of. 235 | /// 236 | /// 237 | /// If the is currently associated with a , the 238 | /// collection of that ; otherwise, . 239 | /// 240 | protected override System.Collections.IEnumerable ItemCollection 241 | { 242 | get 243 | { 244 | if( Owner != null ) 245 | return Owner.Buttons; 246 | return null; 247 | } 248 | } 249 | 250 | private void CheckDuplicateButton(ButtonType type, TaskDialogItem itemToExclude) 251 | { 252 | if( type != ButtonType.Custom && Owner != null ) 253 | { 254 | foreach( TaskDialogButton button in Owner.Buttons ) 255 | { 256 | if( button != this && button != itemToExclude && button.ButtonType == type ) 257 | throw new InvalidOperationException(Properties.Resources.DuplicateButtonTypeError); 258 | } 259 | } 260 | } 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogButtonStyle.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | /// 24 | /// Indicates the display style of custom buttons on a task dialog. 25 | /// 26 | public enum TaskDialogButtonStyle 27 | { 28 | /// 29 | /// Custom buttons are displayed as regular buttons. 30 | /// 31 | Standard, 32 | /// 33 | /// Custom buttons are displayed as command links using a standard task dialog glyph. 34 | /// 35 | CommandLinks, 36 | /// 37 | /// Custom buttons are displayed as command links without a glyph. 38 | /// 39 | CommandLinksNoIcon 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogDesigner.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.ComponentModel.Design; 21 | using System.ComponentModel; 22 | 23 | namespace Ookii.Dialogs.Wpf 24 | { 25 | class TaskDialogDesigner : ComponentDesigner 26 | { 27 | public override DesignerVerbCollection Verbs 28 | { 29 | get 30 | { 31 | DesignerVerbCollection verbs = new DesignerVerbCollection(); 32 | verbs.Add(new DesignerVerb(Properties.Resources.Preview, new EventHandler(Preview))); 33 | return verbs; 34 | } 35 | } 36 | 37 | private void Preview(object sender, EventArgs e) 38 | { 39 | ((TaskDialog)Component).ShowDialog(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogIcon.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | /// 24 | /// Indicates the icon to use for a task dialog. 25 | /// 26 | public enum TaskDialogIcon 27 | { 28 | /// 29 | /// A custom icon or no icon if no custom icon is specified. 30 | /// 31 | Custom, 32 | /// 33 | /// System warning icon. 34 | /// 35 | Warning = 0xFFFF, // MAKEINTRESOURCEW(-1) 36 | /// 37 | /// System Error icon. 38 | /// 39 | Error = 0xFFFE, // MAKEINTRESOURCEW(-2) 40 | /// 41 | /// System Information icon. 42 | /// 43 | Information = 0xFFFD, // MAKEINTRESOURCEW(-3) 44 | /// 45 | /// Shield icon. 46 | /// 47 | Shield = 0xFFFC, // MAKEINTRESOURCEW(-4) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogItem.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.ComponentModel; 19 | using System.Collections.Generic; 20 | using System.Diagnostics; 21 | using System.Text; 22 | using System.Collections; 23 | 24 | namespace Ookii.Dialogs.Wpf 25 | { 26 | /// 27 | /// Represents a button or radio button on a task dialog. 28 | /// 29 | /// 30 | [ToolboxItem(false), DesignTimeVisible(false), DefaultProperty("Text"), DefaultEvent("Click")] 31 | public abstract partial class TaskDialogItem : Component 32 | { 33 | private TaskDialog _owner; 34 | private int _id; 35 | private bool _enabled = true; 36 | private string _text; 37 | 38 | /// 39 | /// Initializes a new instance of the class. 40 | /// 41 | protected TaskDialogItem() 42 | { 43 | InitializeComponent(); 44 | } 45 | 46 | /// 47 | /// Initializes a new instance of the class with the specified container. 48 | /// 49 | /// The to add the to. 50 | protected TaskDialogItem(IContainer container) 51 | { 52 | if( container != null ) 53 | container.Add(this); 54 | 55 | InitializeComponent(); 56 | } 57 | 58 | internal TaskDialogItem(int id) 59 | { 60 | InitializeComponent(); 61 | 62 | // The item cannot have an owner at this point, so it's not needed to check for duplicates, 63 | // which is why we can safely use the field and not the property, avoiding the virtual method call. 64 | _id = id; 65 | } 66 | 67 | /// 68 | /// Gets the that owns this . 69 | /// 70 | /// 71 | /// The that owns this . 72 | /// 73 | /// 74 | /// This property is set automatically when the is added 75 | /// to the or 76 | /// collection of a . 77 | /// 78 | [Browsable(false)] 79 | public TaskDialog Owner 80 | { 81 | get { return _owner; } 82 | internal set 83 | { 84 | _owner = value; 85 | AutoAssignId(); 86 | } 87 | } 88 | 89 | /// 90 | /// Gets or sets the text of the item. 91 | /// 92 | /// 93 | /// The text of the item. The default value is an empty string (""). 94 | /// 95 | /// 96 | /// 97 | /// For buttons, this property is ignored if is any value other 98 | /// than . 99 | /// 100 | /// 101 | [Localizable(true), Category("Appearance"), Description("The text of the item."), DefaultValue("")] 102 | public string Text 103 | { 104 | get { return _text ?? string.Empty; } 105 | set 106 | { 107 | _text = value; 108 | UpdateOwner(); 109 | } 110 | } 111 | 112 | /// 113 | /// Gets or sets a value that indicates whether the item is enabled. 114 | /// 115 | /// 116 | /// if this item is enabled; otherwise, . 117 | /// 118 | /// 119 | /// If a button or radio button is not enabled, it will be grayed out and cannot be 120 | /// selected or clicked. 121 | /// 122 | [Category("Behavior"), Description("Indicates whether the item is enabled."), DefaultValue(true)] 123 | public bool Enabled 124 | { 125 | get { return _enabled; } 126 | set 127 | { 128 | _enabled = value; 129 | if( Owner != null ) 130 | { 131 | Owner.SetItemEnabled(this); 132 | } 133 | } 134 | } 135 | 136 | /// 137 | /// Gets or sets the ID of the item. 138 | /// 139 | /// 140 | /// The unique identifier of the item. 141 | /// 142 | /// 143 | /// 144 | /// The identifier of an item must be unique for the type of item on the task dialog (i.e. no two 145 | /// buttons can have the same id, no two radio buttons can have the same id, but a radio button 146 | /// can have the same id as a button). 147 | /// 148 | /// 149 | /// If this property is zero when the is added to the 150 | /// or collection of a task dialog, it will automatically be set 151 | /// to the next available id value. 152 | /// 153 | /// 154 | [Category("Data"), Description("The id of the item."), DefaultValue(0)] 155 | internal virtual int Id 156 | { 157 | get { return _id; } 158 | set 159 | { 160 | CheckDuplicateId(null, value); 161 | _id = value; 162 | UpdateOwner(); 163 | } 164 | } 165 | 166 | /// 167 | /// Simulates a click on the task dialog item. 168 | /// 169 | /// 170 | /// This method is available only while the task dialog is being displayed. You would typically call 171 | /// it from one of the events fired by the class while the dialog is visible. 172 | /// 173 | /// 174 | /// The task dialog is not being displayed 175 | /// -or- 176 | /// The item has no associated task dialog. 177 | /// 178 | public void Click() 179 | { 180 | if( Owner == null ) 181 | throw new InvalidOperationException(Properties.Resources.NoAssociatedTaskDialogError); 182 | 183 | Owner.ClickItem(this); 184 | } 185 | 186 | /// 187 | /// When implemented in a derived class, gets the item collection on a task dialog that this type of item is 188 | /// part of. 189 | /// 190 | /// 191 | /// For items, the 192 | /// collection of the instance this item is part of. For items, the 193 | /// collection of the instance this item is part of. If the is not 194 | /// currently associated with a , . 195 | /// 196 | /// 197 | /// The collection returned by this property is used to determine if there are any items with duplicate IDs. 198 | /// 199 | protected abstract IEnumerable ItemCollection 200 | { 201 | get; 202 | } 203 | 204 | /// 205 | /// Causes a full update of the owner dialog. 206 | /// 207 | /// 208 | /// 209 | /// When this method is called, the owner dialog will be updated to reflect the 210 | /// current state of the object. 211 | /// 212 | /// 213 | /// When the has no owner, or the owner is not being 214 | /// displayed, this method has no effect. 215 | /// 216 | /// 217 | protected void UpdateOwner() 218 | { 219 | if( Owner != null ) 220 | Owner.UpdateDialog(); 221 | } 222 | 223 | internal virtual void CheckDuplicate(TaskDialogItem itemToExclude) 224 | { 225 | CheckDuplicateId(itemToExclude, _id); 226 | } 227 | 228 | internal virtual void AutoAssignId() 229 | { 230 | if( ItemCollection != null ) 231 | { 232 | int highestId = 9; 233 | foreach( TaskDialogItem item in ItemCollection ) 234 | { 235 | if( item.Id > highestId ) 236 | highestId = item.Id; 237 | } 238 | Id = highestId + 1; 239 | } 240 | } 241 | 242 | private void CheckDuplicateId(TaskDialogItem itemToExclude, int id) 243 | { 244 | if( id != 0 ) 245 | { 246 | IEnumerable items = ItemCollection; 247 | if( items != null ) 248 | { 249 | foreach( TaskDialogItem item in items ) 250 | { 251 | if( item != this && item != itemToExclude && item.Id == id ) 252 | throw new InvalidOperationException(Properties.Resources.DuplicateItemIdError); 253 | } 254 | } 255 | } 256 | } 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogItem.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Ookii.Dialogs.Wpf 2 | { 3 | partial class TaskDialogItem 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// if managed resources should be disposed; otherwise, . 14 | protected override void Dispose(bool disposing) 15 | { 16 | try 17 | { 18 | if( disposing && (components != null) ) 19 | { 20 | components.Dispose(); 21 | } 22 | } 23 | finally 24 | { 25 | base.Dispose(disposing); 26 | } 27 | } 28 | 29 | #region Component Designer generated code 30 | 31 | /// 32 | /// Required method for Designer support - do not modify 33 | /// the contents of this method with the code editor. 34 | /// 35 | private void InitializeComponent() 36 | { 37 | components = new System.ComponentModel.Container(); 38 | } 39 | 40 | #endregion 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogItemClickedEventArgs.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.ComponentModel; 21 | 22 | namespace Ookii.Dialogs.Wpf 23 | { 24 | /// 25 | /// Provides data for the event. 26 | /// 27 | /// 28 | public class TaskDialogItemClickedEventArgs : CancelEventArgs 29 | { 30 | private readonly TaskDialogItem _item; 31 | 32 | /// 33 | /// Initializes a new instance of the class with the specified item. 34 | /// 35 | /// The that was clicked. 36 | public TaskDialogItemClickedEventArgs(TaskDialogItem item) 37 | { 38 | _item = item; 39 | } 40 | 41 | /// 42 | /// Gets the item that was clicked. 43 | /// 44 | /// 45 | /// The that was clicked. 46 | /// 47 | public TaskDialogItem Item 48 | { 49 | get { return _item; } 50 | } 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogItemCollection.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.Collections.ObjectModel; 21 | 22 | namespace Ookii.Dialogs.Wpf 23 | { 24 | /// 25 | /// Represents a list of objects. 26 | /// 27 | /// The type of the task dialog item. 28 | /// 29 | public class TaskDialogItemCollection : Collection where T : TaskDialogItem 30 | { 31 | private TaskDialog _owner; 32 | 33 | internal TaskDialogItemCollection(TaskDialog owner) 34 | { 35 | _owner = owner; 36 | } 37 | 38 | /// 39 | /// Overrides the method. 40 | /// 41 | protected override void ClearItems() 42 | { 43 | foreach( T item in this ) 44 | { 45 | item.Owner = null; 46 | } 47 | base.ClearItems(); 48 | _owner.UpdateDialog(); 49 | } 50 | 51 | /// 52 | /// Overrides the method. 53 | /// 54 | /// The zero-based index at which should be inserted. 55 | /// The object to insert. May not be . 56 | /// is . 57 | /// The specified in is already associated with a different task dialog. 58 | /// The specified in has a duplicate id or button type. 59 | /// 60 | /// 61 | /// is less than zero. 62 | /// 63 | /// 64 | /// -or- 65 | /// 66 | /// 67 | /// is equal to or greater than . 68 | /// 69 | /// 70 | protected override void InsertItem(int index, T item) 71 | { 72 | if( item == null ) 73 | throw new ArgumentNullException("item"); 74 | 75 | if( item.Owner != null ) 76 | throw new ArgumentException(Properties.Resources.TaskDialogItemHasOwnerError); 77 | 78 | item.Owner = _owner; 79 | try 80 | { 81 | item.CheckDuplicate(null); 82 | } 83 | catch( InvalidOperationException ) 84 | { 85 | item.Owner = null; 86 | throw; 87 | } 88 | base.InsertItem(index, item); 89 | _owner.UpdateDialog(); 90 | } 91 | 92 | /// 93 | /// Overrides the method. 94 | /// 95 | /// The zero-based index of the element to remove. 96 | /// 97 | /// 98 | /// is less than zero. 99 | /// 100 | /// 101 | /// -or- 102 | /// 103 | /// 104 | /// is equal to or greater than . 105 | /// 106 | /// 107 | protected override void RemoveItem(int index) 108 | { 109 | base[index].Owner = null; 110 | base.RemoveItem(index); 111 | _owner.UpdateDialog(); 112 | } 113 | 114 | /// 115 | /// Overrides the method. 116 | /// 117 | /// The zero-based index of the element to replace. 118 | /// The new value for the element at the specified index. May not be . 119 | /// is . 120 | /// The specified in is already associated with a different task dialog. 121 | /// The specified in has a duplicate id or button type. 122 | /// 123 | /// 124 | /// is less than zero. 125 | /// 126 | /// 127 | /// -or- 128 | /// 129 | /// 130 | /// is equal to or greater than . 131 | /// 132 | /// 133 | protected override void SetItem(int index, T item) 134 | { 135 | if( item == null ) 136 | throw new ArgumentNullException("item"); 137 | 138 | if( base[index] != item ) 139 | { 140 | if( item.Owner != null ) 141 | throw new ArgumentException(Properties.Resources.TaskDialogItemHasOwnerError); 142 | item.Owner = _owner; 143 | try 144 | { 145 | item.CheckDuplicate(base[index]); 146 | } 147 | catch( InvalidOperationException ) 148 | { 149 | item.Owner = null; 150 | throw; 151 | } 152 | base[index].Owner = null; 153 | base.SetItem(index, item); 154 | _owner.UpdateDialog(); 155 | } 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TaskDialogRadioButton.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.ComponentModel; 21 | 22 | namespace Ookii.Dialogs.Wpf 23 | { 24 | /// 25 | /// A radio button on a task dialog. 26 | /// 27 | /// 28 | public class TaskDialogRadioButton : TaskDialogItem 29 | { 30 | private bool _checked; 31 | 32 | /// 33 | /// Initializes a new instance of the class. 34 | /// 35 | public TaskDialogRadioButton() 36 | { 37 | } 38 | 39 | /// 40 | /// Initializes a new instance of the class with the specified container. 41 | /// 42 | /// The to add the to. 43 | public TaskDialogRadioButton(IContainer container) 44 | : base(container) 45 | { 46 | } 47 | 48 | /// 49 | /// Gets or sets a value that indicates whether the radio button is checked. 50 | /// 51 | /// 52 | /// if the radio button is checked; otherwise, . 53 | /// The default value is . 54 | /// 55 | /// 56 | /// Setting this property while the dialog is being displayed has no effect. Instead, use the 57 | /// method to check a particular radio button. 58 | /// 59 | [Category("Appearance"), Description("Indicates whether the radio button is checked."), DefaultValue(false)] 60 | public bool Checked 61 | { 62 | get { return _checked; } 63 | set 64 | { 65 | _checked = value; 66 | if( value && Owner != null ) 67 | { 68 | foreach( TaskDialogRadioButton radioButton in Owner.RadioButtons ) 69 | { 70 | if( radioButton != this ) 71 | radioButton.Checked = false; 72 | } 73 | } 74 | } 75 | } 76 | 77 | /// 78 | /// Gets the collection that items of this type are part of. 79 | /// 80 | /// 81 | /// If the is currently associated with a , the 82 | /// collection of that ; otherwise, . 83 | /// 84 | protected override System.Collections.IEnumerable ItemCollection 85 | { 86 | get 87 | { 88 | if( Owner != null ) 89 | return Owner.RadioButtons; 90 | return null; 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/TimerEventArgs.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Ookii.Dialogs.Wpf 22 | { 23 | /// 24 | /// Provides data for the event. 25 | /// 26 | /// 27 | public class TimerEventArgs : EventArgs 28 | { 29 | private int _tickCount; 30 | private bool _resetTickCount; 31 | 32 | /// 33 | /// Initializes a new instance of the class with the specified tick count. 34 | /// 35 | /// The tick count. 36 | public TimerEventArgs(int tickCount) 37 | { 38 | _tickCount = tickCount; 39 | } 40 | 41 | /// 42 | /// Gets or sets a value that indicates whether the tick count should be reset. 43 | /// 44 | /// 45 | /// to reset the tick count after the event handler returns; otherwise, . 46 | /// The default value is . 47 | /// 48 | public bool ResetTickCount 49 | { 50 | get { return _resetTickCount; } 51 | set { _resetTickCount = value; } 52 | } 53 | 54 | /// 55 | /// Gets the current tick count of the timer. 56 | /// 57 | /// 58 | /// The number of milliseconds that has elapsed since the dialog was created or since the last time the event handler returned 59 | /// with the property set to . 60 | /// 61 | public int TickCount 62 | { 63 | get { return _tickCount; } 64 | } 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/VistaFileDialogEvents.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | 19 | namespace Ookii.Dialogs.Wpf 20 | { 21 | class VistaFileDialogEvents : IFileDialogEvents, IFileDialogControlEvents 22 | { 23 | private VistaFileDialog _dialog; 24 | 25 | public VistaFileDialogEvents(VistaFileDialog dialog) 26 | { 27 | _dialog = dialog ?? throw new ArgumentNullException("dialog"); 28 | } 29 | 30 | #region IFileDialogEvents Members 31 | 32 | HRESULT IFileDialogEvents.OnFileOk(IFileDialog pfd) 33 | { 34 | if (_dialog.DoFileOk(pfd)) 35 | return HRESULT.S_OK; 36 | else 37 | return HRESULT.S_FALSE; 38 | } 39 | 40 | HRESULT IFileDialogEvents.OnFolderChanging(IFileDialog pfd, IShellItem psiFolder) => HRESULT.S_OK; 41 | 42 | public void OnFolderChange(IFileDialog pfd) 43 | { 44 | } 45 | 46 | public void OnSelectionChange(IFileDialog pfd) 47 | { 48 | } 49 | 50 | public unsafe void OnShareViolation(IFileDialog pfd, IShellItem psi, FDE_SHAREVIOLATION_RESPONSE* pResponse) 51 | { 52 | *pResponse = FDE_SHAREVIOLATION_RESPONSE.FDESVR_DEFAULT; 53 | } 54 | 55 | public void OnTypeChange(IFileDialog pfd) 56 | { 57 | } 58 | 59 | public unsafe void OnOverwrite(IFileDialog pfd, IShellItem psi, FDE_OVERWRITE_RESPONSE* pResponse) 60 | { 61 | *pResponse = FDE_OVERWRITE_RESPONSE.FDEOR_DEFAULT; 62 | } 63 | 64 | #endregion 65 | 66 | #region IFileDialogControlEvents Members 67 | 68 | public void OnItemSelected(IFileDialogCustomize pfdc, uint dwIDCtl, uint dwIDItem) 69 | { 70 | } 71 | 72 | public void OnButtonClicked(IFileDialogCustomize pfdc, uint dwIDCtl) 73 | { 74 | } 75 | 76 | public void OnCheckButtonToggled(IFileDialogCustomize pfdc, uint dwIDCtl, BOOL bChecked) 77 | { 78 | } 79 | 80 | public void OnControlActivating(IFileDialogCustomize pfdc, uint dwIDCtl) 81 | { 82 | } 83 | 84 | #endregion 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/VistaFolderBrowserDialog.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/src/Ookii.Dialogs.Wpf/VistaFolderBrowserDialog.bmp -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/VistaOpenFileDialog.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/src/Ookii.Dialogs.Wpf/VistaOpenFileDialog.bmp -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/VistaOpenFileDialog.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.IO; 21 | using System.ComponentModel; 22 | using Microsoft.Win32; 23 | using Ookii.Dialogs.Wpf.Interop; 24 | 25 | namespace Ookii.Dialogs.Wpf 26 | { 27 | /// 28 | /// Prompts the user to open a file. 29 | /// 30 | /// 31 | /// 32 | /// Windows Vista provides a new style of common file dialog, with several new features (both from 33 | /// the user's and the programmers perspective). 34 | /// 35 | /// 36 | /// This class will use the Vista-style file dialogs if possible, and automatically fall back to the old-style 37 | /// dialog on versions of Windows older than Vista. This class is aimed at applications that 38 | /// target both Windows Vista and older versions of Windows, and therefore does not provide any 39 | /// of the new APIs provided by Vista's file dialogs. 40 | /// 41 | /// 42 | /// This class precisely duplicates the public interface of so you can just replace 43 | /// any instances of with the without any further changes 44 | /// to your code. 45 | /// 46 | /// 47 | /// 48 | [Description("Prompts the user to open a file.")] 49 | public sealed class VistaOpenFileDialog : VistaFileDialog 50 | { 51 | private bool _showReadOnly; 52 | private bool _readOnlyChecked; 53 | private const int _openDropDownId = 0x4002; 54 | private const int _openItemId = 0x4003; 55 | private const int _readOnlyItemId = 0x4004; 56 | 57 | /// 58 | /// Creates a new instance of class. 59 | /// 60 | public VistaOpenFileDialog() 61 | { 62 | if( !IsVistaFileDialogSupported ) 63 | DownlevelDialog = new OpenFileDialog(); 64 | } 65 | 66 | #region Public Properties 67 | 68 | /// 69 | /// Gets or sets a value indicating whether the dialog box displays a warning if the user specifies a file name that does not exist. 70 | /// 71 | /// 72 | /// if the dialog box displays a warning if the user specifies a file name that does not exist; otherwise, . The default value is . 73 | /// 74 | [DefaultValue(true), Description("A value indicating whether the dialog box displays a warning if the user specifies a file name that does not exist.")] 75 | public override bool CheckFileExists 76 | { 77 | get 78 | { 79 | return base.CheckFileExists; 80 | } 81 | set 82 | { 83 | base.CheckFileExists = value; 84 | } 85 | } 86 | 87 | /// 88 | /// Gets or sets a value indicating whether the dialog box allows multiple files to be selected. 89 | /// 90 | /// 91 | /// if the dialog box allows multiple files to be selected together or concurrently; otherwise, . 92 | /// The default value is . 93 | /// 94 | [Description("A value indicating whether the dialog box allows multiple files to be selected."), DefaultValue(false), Category("Behavior")] 95 | public bool Multiselect 96 | { 97 | get 98 | { 99 | if( DownlevelDialog != null ) 100 | return ((OpenFileDialog)DownlevelDialog).Multiselect; 101 | return GetOption(FILEOPENDIALOGOPTIONS.FOS_ALLOWMULTISELECT); 102 | } 103 | set 104 | { 105 | if( DownlevelDialog != null ) 106 | ((OpenFileDialog)DownlevelDialog).Multiselect = value; 107 | 108 | SetOption(FILEOPENDIALOGOPTIONS.FOS_ALLOWMULTISELECT, value); 109 | } 110 | } 111 | 112 | /// 113 | /// Gets or sets a value indicating whether the dialog box contains a read-only check box. 114 | /// 115 | /// 116 | /// if the dialog box contains a read-only check box; otherwise, . The default value is . 117 | /// 118 | /// 119 | /// If the Vista style dialog is used, this property can only be used to determine whether the user chose 120 | /// Open as read-only on the dialog; setting it in code will have no effect. 121 | /// 122 | [Description("A value indicating whether the dialog box contains a read-only check box."), Category("Behavior"), DefaultValue(false)] 123 | public bool ShowReadOnly 124 | { 125 | get 126 | { 127 | if( DownlevelDialog != null ) 128 | return ((OpenFileDialog)DownlevelDialog).ShowReadOnly; 129 | return _showReadOnly; 130 | } 131 | set 132 | { 133 | if( DownlevelDialog != null ) 134 | ((OpenFileDialog)DownlevelDialog).ShowReadOnly = value; 135 | else 136 | _showReadOnly = value; 137 | } 138 | } 139 | 140 | /// 141 | /// Gets or sets a value indicating whether the read-only check box is selected. 142 | /// 143 | /// 144 | /// if the read-only check box is selected; otherwise, . The default value is . 145 | /// 146 | [DefaultValue(false), Description("A value indicating whether the read-only check box is selected."), Category("Behavior")] 147 | public bool ReadOnlyChecked 148 | { 149 | get 150 | { 151 | if( DownlevelDialog != null ) 152 | return ((OpenFileDialog)DownlevelDialog).ReadOnlyChecked; 153 | return _readOnlyChecked; 154 | } 155 | set 156 | { 157 | if( DownlevelDialog != null ) 158 | ((OpenFileDialog)DownlevelDialog).ReadOnlyChecked = value; 159 | else 160 | _readOnlyChecked = value; 161 | } 162 | } 163 | 164 | #endregion 165 | 166 | #region Public Methods 167 | 168 | /// 169 | /// Resets all properties to their default values. 170 | /// 171 | public override void Reset() 172 | { 173 | base.Reset(); 174 | if( DownlevelDialog == null ) 175 | { 176 | CheckFileExists = true; 177 | _showReadOnly = false; 178 | _readOnlyChecked = false; 179 | } 180 | } 181 | 182 | /// 183 | /// Opens the file selected by the user, with read-only permission. The file is specified by the FileName property. 184 | /// 185 | /// A Stream that specifies the read-only file selected by the user. 186 | /// The file name is . 187 | public System.IO.Stream OpenFile() 188 | { 189 | if( DownlevelDialog != null ) 190 | return ((OpenFileDialog)DownlevelDialog).OpenFile(); 191 | else 192 | { 193 | string fileName = FileName; 194 | return new FileStream(fileName, FileMode.Open, FileAccess.Read); 195 | } 196 | } 197 | 198 | #endregion 199 | 200 | #region Internal Methods 201 | 202 | internal override IFileDialog CreateFileDialog() 203 | { 204 | return new NativeFileOpenDialog(); 205 | } 206 | 207 | internal override void SetDialogProperties(IFileDialog dialog) 208 | { 209 | base.SetDialogProperties(dialog); 210 | if( _showReadOnly ) 211 | { 212 | IFileDialogCustomize customize = (IFileDialogCustomize)dialog; 213 | customize.EnableOpenDropDown(_openDropDownId); 214 | customize.AddControlItem(_openDropDownId, _openItemId, ComDlgResources.LoadString(ComDlgResources.ComDlgResourceId.OpenButton)); 215 | customize.AddControlItem(_openDropDownId, _readOnlyItemId, ComDlgResources.LoadString(ComDlgResources.ComDlgResourceId.ReadOnly)); 216 | } 217 | } 218 | 219 | internal unsafe override void GetResult(IFileDialog dialog) 220 | { 221 | if( Multiselect ) 222 | { 223 | ((IFileOpenDialog)dialog).GetResults(out var results); 224 | results.GetCount(out uint count); 225 | string[] fileNames = new string[count]; 226 | for( uint x = 0; x < count; ++x ) 227 | { 228 | results.GetItemAt(x, out IShellItem item); 229 | item.GetDisplayName(SIGDN.SIGDN_FILESYSPATH,out var ptr); 230 | fileNames[x] = ptr.ToString(); 231 | } 232 | FileNamesInternal = fileNames; 233 | 234 | } 235 | else 236 | FileNamesInternal = null; 237 | 238 | if( ShowReadOnly ) 239 | { 240 | IFileDialogCustomize customize = (IFileDialogCustomize)dialog; 241 | uint selected; 242 | customize.GetSelectedControlItem(_openDropDownId, &selected); 243 | _readOnlyChecked = (selected == _readOnlyItemId); 244 | } 245 | 246 | base.GetResult(dialog); 247 | } 248 | 249 | #endregion 250 | 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/VistaSaveFileDialog.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ookii-dialogs/ookii-dialogs-wpf/6eef3191f163af405759669f70f97782573f0d7b/src/Ookii.Dialogs.Wpf/VistaSaveFileDialog.bmp -------------------------------------------------------------------------------- /src/Ookii.Dialogs.Wpf/VistaSaveFileDialog.cs: -------------------------------------------------------------------------------- 1 | #region Copyright 2009-2021 Ookii Dialogs Contributors 2 | // 3 | // Licensed under the BSD 3-Clause License (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://opensource.org/licenses/BSD-3-Clause 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | #endregion 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | using System.IO; 21 | using System.ComponentModel; 22 | using Microsoft.Win32; 23 | using Ookii.Dialogs.Wpf.Interop; 24 | using System.Windows; 25 | 26 | namespace Ookii.Dialogs.Wpf 27 | { 28 | /// 29 | /// Prompts the user to select a location for saving a file. 30 | /// 31 | /// 32 | /// This class will use the Vista style save file dialog if possible, and automatically fall back to the old-style 33 | /// dialog on versions of Windows older than Vista. 34 | /// 35 | /// 36 | /// 37 | /// Windows Vista provides a new style of common file dialog, with several new features (both from 38 | /// the user's and the programmers perspective). 39 | /// 40 | /// 41 | /// This class will use the Vista-style file dialogs if possible, and automatically fall back to the old-style 42 | /// dialog on versions of Windows older than Vista. This class is aimed at applications that 43 | /// target both Windows Vista and older versions of Windows, and therefore does not provide any 44 | /// of the new APIs provided by Vista's file dialogs. 45 | /// 46 | /// 47 | /// This class precisely duplicates the public interface of so you can just replace 48 | /// any instances of with the without any further changes 49 | /// to your code. 50 | /// 51 | /// 52 | /// 53 | [Designer("System.Windows.Forms.Design.SaveFileDialogDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), Description("Prompts the user to open a file.")] 54 | public sealed class VistaSaveFileDialog : VistaFileDialog 55 | { 56 | /// 57 | /// Creates a new instance of class. 58 | /// 59 | public VistaSaveFileDialog() 60 | { 61 | if( !IsVistaFileDialogSupported ) 62 | DownlevelDialog = new SaveFileDialog(); 63 | } 64 | 65 | #region Public Properties 66 | 67 | /// 68 | /// Gets or sets a value indicating whether the dialog box prompts the user for permission to create a file if the 69 | /// user specifies a file that does not exist. 70 | /// 71 | /// 72 | /// if the dialog box prompts the user before creating a file if the user specifies a file name that does not exist; 73 | /// if the dialog box automatically creates the new file without prompting the user for permission. The default 74 | /// value is . 75 | /// 76 | [DefaultValue(false), Category("Behavior"), Description("A value indicating whether the dialog box prompts the user for permission to create a file if the user specifies a file that does not exist.")] 77 | public bool CreatePrompt 78 | { 79 | get 80 | { 81 | if( DownlevelDialog != null ) 82 | return ((SaveFileDialog)DownlevelDialog).CreatePrompt; 83 | return GetOption(FILEOPENDIALOGOPTIONS.FOS_CREATEPROMPT); 84 | } 85 | set 86 | { 87 | if( DownlevelDialog != null ) 88 | ((SaveFileDialog)DownlevelDialog).CreatePrompt = value; 89 | else 90 | SetOption(FILEOPENDIALOGOPTIONS.FOS_CREATEPROMPT, value); 91 | } 92 | } 93 | 94 | /// 95 | /// Gets or sets a value indicating whether the Save As dialog box displays a warning if the user 96 | /// specifies a file name that already exists. 97 | /// 98 | /// 99 | /// if the dialog box prompts the user before overwriting an existing file if the user specifies a file 100 | /// name that already exists; if the dialog box automatically overwrites the existing file without 101 | /// prompting the user for permission. The default value is . 102 | /// 103 | [Category("Behavior"), DefaultValue(true), Description("A value indicating whether the Save As dialog box displays a warning if the user specifies a file name that already exists.")] 104 | public bool OverwritePrompt 105 | { 106 | get 107 | { 108 | if( DownlevelDialog != null ) 109 | return ((SaveFileDialog)DownlevelDialog).OverwritePrompt; 110 | return GetOption(FILEOPENDIALOGOPTIONS.FOS_OVERWRITEPROMPT); 111 | } 112 | set 113 | { 114 | if( DownlevelDialog != null ) 115 | ((SaveFileDialog)DownlevelDialog).OverwritePrompt = value; 116 | else 117 | SetOption(FILEOPENDIALOGOPTIONS.FOS_OVERWRITEPROMPT, value); 118 | } 119 | } 120 | 121 | #endregion 122 | 123 | #region Public Methods 124 | 125 | /// 126 | /// Resets all properties to their default values. 127 | /// 128 | public override void Reset() 129 | { 130 | base.Reset(); 131 | if( DownlevelDialog == null ) 132 | { 133 | OverwritePrompt = true; 134 | } 135 | } 136 | 137 | /// 138 | /// Opens the file with read/write permission selected by the user. 139 | /// 140 | /// The read/write file selected by the user. 141 | /// The file name is . 142 | public System.IO.Stream OpenFile() 143 | { 144 | if( DownlevelDialog != null ) 145 | return ((SaveFileDialog)DownlevelDialog).OpenFile(); 146 | else 147 | { 148 | string fileName = FileName; 149 | return new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite); 150 | } 151 | } 152 | 153 | #endregion 154 | 155 | #region Protected Methods 156 | 157 | /// 158 | /// Raises the event. 159 | /// 160 | /// A that contains the event data. 161 | protected override void OnFileOk(CancelEventArgs e) 162 | { 163 | // For reasons unknown, .Net puts the OFN_FILEMUSTEXIST and OFN_CREATEPROMPT flags on the save file dialog despite 164 | // the fact that these flags only works on open file dialogs, and then prompts manually. Similarly, the 165 | // FOS_CREATEPROMPT and FOS_FILEMUSTEXIST flags don't actually work on IFileSaveDialog, so we have to implement 166 | // the prompt manually. 167 | if( DownlevelDialog == null ) 168 | { 169 | if( CheckFileExists && !File.Exists(FileName) ) 170 | { 171 | PromptUser(ComDlgResources.FormatString(ComDlgResources.ComDlgResourceId.FileNotFound, Path.GetFileName(FileName)), MessageBoxButton.OK, MessageBoxImage.Exclamation, MessageBoxResult.OK); 172 | e.Cancel = true; 173 | return; 174 | } 175 | if( CreatePrompt && !File.Exists(FileName) ) 176 | { 177 | if( !PromptUser(ComDlgResources.FormatString(ComDlgResources.ComDlgResourceId.CreatePrompt, Path.GetFileName(FileName)), MessageBoxButton.YesNo, MessageBoxImage.Exclamation, MessageBoxResult.No) ) 178 | { 179 | e.Cancel = true; 180 | return; 181 | } 182 | } 183 | } 184 | base.OnFileOk(e); 185 | } 186 | 187 | #endregion 188 | 189 | #region Internal Methods 190 | 191 | internal override IFileDialog CreateFileDialog() 192 | { 193 | return new NativeFileSaveDialog(); 194 | } 195 | 196 | #endregion 197 | 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs/Ookii.Dialogs.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0-windows;net5.0-windows;netcoreapp3.1;net462 5 | true 6 | true 7 | 8 | true 9 | true 10 | 11 | $(NoWarn);NU5048;NU5128 12 | true 13 | 14 | 15 | 16 | 17 | Ookii.Dialogs 18 | 0.0.1-local 19 | Ookii Dialogs Contributors 20 | DEPRECATED. This package has been replaced by the package Ookii.Dialogs.Wpf. 21 | Copyright (c) 2009-2021 Ookii Dialogs Contributors 22 | ookii;dialogs;wpf;windows-presentation-foundation;progress-dialog;task-dialog;credential-dialog;common-file-dialog 23 | BSD-3-Clause 24 | images\icon.png 25 | https://cdn.jsdelivr.net/gh/ookii-dialogs/ookii-dialogs-wpf/assets/ookii-dialogs-deprecated-nuget.png 26 | https://github.com/ookii-dialogs/ookii-dialogs-wpf 27 | https://github.com/ookii-dialogs/ookii-dialogs-wpf/releases 28 | git 29 | https://github.com/ookii-dialogs/ookii-dialogs-wpf.git 30 | false 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 62 | 63 | 64 | <_ProjectReferencesWithBounds Include="@(_ProjectReferencesWithVersions)"> 65 | [$(Version)] 66 | 67 | 68 | 69 | <_ProjectReferencesWithVersions Remove="@(_ProjectReferencesWithVersions)" /> 70 | <_ProjectReferencesWithVersions Include="@(_ProjectReferencesWithBounds)" /> 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs/build/Ookii.Dialogs.targets: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | 18 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 19 | 20 | 21 | 24 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Ookii.Dialogs/buildMultiTargeting/Ookii.Dialogs.targets: -------------------------------------------------------------------------------- 1 |  14 | 15 | 16 | 17 | 18 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 19 | 20 | 21 | 22 | 23 | 24 | --------------------------------------------------------------------------------