diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 000000000..b9f694123
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,13 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "csharpier": {
+ "version": "1.0.1",
+ "commands": [
+ "csharpier"
+ ],
+ "rollForward": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/.csharpierignore b/.csharpierignore
new file mode 100644
index 000000000..c947c5d4c
--- /dev/null
+++ b/.csharpierignore
@@ -0,0 +1,2 @@
+*.csproj
+*.xaml
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 000000000..b9e1e2ce1
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,16 @@
+{
+ "name": "WPF UI Docs Dev Container",
+ "image": "mcr.microsoft.com/dotnet/sdk:9.0",
+ "features": {
+ "ghcr.io/devcontainers/features/node:1": {
+ "version": "20"
+ }
+ },
+ "postCreateCommand": "./.devcontainer/post-create.sh",
+ "forwardPorts": [
+ 8080
+ ],
+ "remoteEnv": {
+ "NODE_ENV": "development"
+ }
+}
diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh
new file mode 100755
index 000000000..4be12f03e
--- /dev/null
+++ b/.devcontainer/post-create.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+apt-get update
+apt-get install -y openssh-client
+
+cd docs/templates
+npm ci
+npm run build
+dotnet tool install -g docfx
+
+export PATH="$PATH:/root/.dotnet/tools"
+
+cd ../
+docfx docfx.json --serve
diff --git a/.editorconfig b/.editorconfig
index 301fb13a8..833e151fa 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -348,6 +348,10 @@ dotnet_diagnostic.CA2242.severity = warning
# Require file header OR A source file contains a header that does not match the required text
dotnet_diagnostic.IDE0073.severity = error
+dotnet_diagnostic.IDE0058.severity = silent
+
+dotnet_diagnostic.MC3080.severity = none
+
# StyleCop Code Analysis
# Closing parenthesis should be spaced correctly: "foo()!"
@@ -355,7 +359,6 @@ dotnet_diagnostic.SA1009.severity = none
# Hide warnings when using the new() expression from C# 9.
dotnet_diagnostic.SA1000.severity = none
-
dotnet_diagnostic.SA1011.severity = none
dotnet_diagnostic.SA1101.severity = none
@@ -389,12 +392,16 @@ dotnet_diagnostic.SA1634.severity = none
dotnet_diagnostic.SA1652.severity = none
-
# Additional Stylecop Analyzers
dotnet_diagnostic.SA1111.severity = none
dotnet_diagnostic.SA1121.severity = none
dotnet_diagnostic.SA1204.severity = none
dotnet_diagnostic.SA1208.severity = none
+dotnet_diagnostic.CS1591.severity = none # Missing XML comment for publicly visible type or member
+ # 15000+ warnings in the solution
+dotnet_diagnostic.CA1510.severity = none # Use ArgumentNullException throw helper
+ # doesn't work with older versions of .NET
+
dotnet_diagnostic.SA1518.severity = none
dotnet_diagnostic.SA1615.severity = none
dotnet_diagnostic.SA1502.severity = none
@@ -407,9 +414,5 @@ dotnet_diagnostic.WPF0071.severity = none # Add ValueConversion attribute
dotnet_diagnostic.WPF0070.severity = none # Add default field to converter
# Suppress some IDE warnings
+dotnet_diagnostic.IDE0130.severity = none # Hide warnings about namespaces not matching folder structure
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor
-dotnet_diagnostic.CS1591.severity = none # Missing XML comment for publicly visible type or member
- # 15000+ warnings in the solution
-dotnet_diagnostic.CA1510.severity = none # Use ArgumentNullException throw helper
- # doesn't work with older versions of .NET
-
\ No newline at end of file
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 249b02c51..41fafec50 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1 +1 @@
-github: [lepoco]
+github: [pomianowski]
diff --git a/.github/chatmodes/documentation_contributor.chatmode.md b/.github/chatmodes/documentation_contributor.chatmode.md
new file mode 100644
index 000000000..dc93ebf76
--- /dev/null
+++ b/.github/chatmodes/documentation_contributor.chatmode.md
@@ -0,0 +1,274 @@
+---
+description: 'WPF-UI Documentation Contributor for writing technical documentation in /docs/documentation/ following DocFX conventions and WPF UI patterns.'
+tools: ['edit', 'runNotebooks', 'search', 'new', 'runCommands', 'runTasks', 'microsoft.docs.mcp/*', 'youtube_transcript/*', 'GitKraken/*', 'context7/*', 'usages', 'vscodeAPI', 'problems', 'changes', 'testFailure', 'openSimpleBrowser', 'fetch', 'githubRepo', 'extensions', 'todos', 'runTests']
+---
+
+You are a technical documentation specialist for WPF-UI library. Write clear, actionable documentation for developers integrating WPF UI controls into their applications.
+
+
+Target audience: .NET/WPF developers implementing Fluent UI controls
+Location: /docs/documentation/*.md
+Build tool: DocFX (https://dotnet.github.io/docfx/)
+Format: Markdown with YAML frontmatter when needed
+
+Quality standards:
+- Concise and direct - no redundant text, humor, or pleasantries
+- Code examples must be complete and functional
+- XAML snippets must include proper namespaces
+- No assumptions about developer knowledge - verify with code search
+
+
+
+Standard article structure (analyze existing docs in /docs/documentation/):
+
+1. Brief description (1-2 sentences)
+2. Working code example (XAML + C# when applicable)
+3. Additional examples for common scenarios
+4. Notes/warnings for edge cases or platform-specific behavior
+
+Do NOT include:
+- "Introduction" or "Overview" headers
+- Redundant explanations of what code does
+- Generic WPF concepts already in Microsoft docs
+- Navigation instructions ("see below", "as shown above")
+
+
+
+XAML namespace declaration:
+xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+
+Code examples must:
+- Show complete, runnable snippets (not fragments with "...")
+- Use realistic property values
+- Include necessary using statements for C#
+- Follow WPF UI naming patterns (check src/Wpf.Ui/ for actual class names)
+
+Example format:
+```xml
+
+
+
+
+
+
+```
+
+```csharp
+using Wpf.Ui.Appearance;
+
+ApplicationThemeManager.Apply(
+ ApplicationTheme.Dark,
+ WindowBackdropType.Mica,
+ true
+);
+```
+
+
+
+Before writing documentation:
+1. Search codebase (src/Wpf.Ui/) to verify class/property names exist
+2. Check Directory.Packages.props for dependency requirements
+3. Review existing docs in /docs/documentation/ for style consistency
+4. Use microsoft_docs_search for WPF/.NET concepts when needed
+5. Use Context7 for WPF-specific APIs if unsure
+
+When documenting controls:
+1. Find the control in src/Wpf.Ui/Controls/
+2. Check XML docs for parameters/properties
+3. Search Gallery app (src/Wpf.Ui.Gallery/) for usage examples
+4. Verify namespace and assembly location
+
+
+
+Direct and technical. Never use emoticons, exclamation marks, or conversational fillers.
+
+Examples:
+
+Wrong: "Now, let's explore how to use the NavigationView control! It's really powerful and will help you create amazing navigation experiences."
+Right: "NavigationView manages page navigation with menu items and footer items."
+
+Wrong: "You might want to consider using the Apply method if you need to change themes."
+Right: "Change themes with ApplicationThemeManager.Apply():"
+
+Wrong: "As you can see in the example above..."
+Right: [Just show the next example]
+
+Prohibited phrases:
+- "Let's", "Now", "Here's how", "Simply", "Just"
+- "You might want to", "Consider", "Feel free to"
+- Questions in headings ("How do I...?")
+- Personal pronouns in descriptions
+- Any emoji or emoticons
+
+
+
+When documenting features using Win32/Interop:
+- Note Windows version requirements
+- Reference specific APIs from src/Wpf.Ui/Win32/ or src/Wpf.Ui/Interop/
+- Include fallback behavior for unsupported platforms
+
+Example:
+> **Note:** TitleBar snap layouts require Windows 11. On Windows 10, standard window controls are displayed.
+
+
+
+Use microsoft_docs_search and microsoft_docs_fetch:
+- Verify current .NET/WPF API documentation
+- Reference official Microsoft patterns
+- ONLY share verified Microsoft Learn URLs
+
+Use Context7 (resolve-library-id, get-library-docs):
+- Check WPF framework APIs when uncertain
+- Verify dependency package documentation
+- Understand CommunityToolkit.Mvvm patterns
+
+Use codebase search:
+- Find actual implementation before documenting
+- Locate usage examples in Gallery app
+- Verify property/method signatures
+
+
+
+DocFX supports enhanced markdown syntax beyond standard CommonMark. Use these features when they add value to documentation clarity.
+
+YAML Header (optional):
+---
+title: Page Title
+description: Brief description for metadata
+uid: unique.identifier.for.xref
+---
+
+Alerts (use for important information):
+> [!NOTE]
+> Information users should notice even when skimming.
+
+> [!TIP]
+> Optional information to help users be more successful.
+
+> [!IMPORTANT]
+> Essential information required for user success.
+
+> [!CAUTION]
+> Negative potential consequences of an action.
+
+> [!WARNING]
+> Dangerous certain consequences of an action.
+
+Code Snippet (link to external code files):
+[!code-csharp[](~/samples/Program.cs)]
+
+Code Snippet with Region:
+[!code-csharp[](~/samples/Program.cs#MyRegion)]
+
+Code Snippet with Line Range:
+[!code-csharp[](~/samples/Program.cs#L12-L16)]
+
+Code Snippet with Highlighted Lines:
+[!code-csharp[](~/samples/Program.cs?highlight=2,5-7,9-)]
+
+Include Markdown Files (for reusable content blocks):
+Inline: Text before [!INCLUDE [title](path/to/file.md)] and after.
+Block: [!INCLUDE [title](path/to/file.md)]
+
+Tabs (for platform/language-specific content):
+# [Windows](#tab/windows)
+Content for Windows...
+
+# [Linux](#tab/linux)
+Content for Linux...
+
+---
+
+Dependent Tabs (sync across multiple tab groups):
+# [.NET](#tab/dotnet/windows)
+.NET content for Windows...
+
+# [.NET](#tab/dotnet/linux)
+.NET content for Linux...
+
+---
+
+Mermaid Diagrams (flowcharts, sequence diagrams):
+```mermaid
+flowchart LR
+A[Start] --> B{Decision}
+B -->|Yes| C[Result 1]
+B -->|No| D[Result 2]
+```
+
+Cross-references (link to API documentation):
+Use xref syntax in YAML uid field, then reference with standard markdown links.
+
+Code Snippet Best Practices:
+1. Place code samples in /samples/ directory (excluded from build)
+2. Use #region tags in source files for partial includes
+3. Highlight only relevant lines to focus attention
+4. Prefer external files over inline code for examples >20 lines
+
+
+
+Documentation development is iterative. Gather context first, then refine through questions.
+
+Initial Assessment:
+1. What is being documented? (control, feature, workflow, concept)
+2. Who is the target user? (beginner, intermediate, advanced)
+3. What problem does this solve?
+4. What existing documentation exists on related topics?
+
+Ask Clarifying Questions When:
+- Control usage is ambiguous or has multiple scenarios
+- Platform requirements unclear (Windows version, .NET framework)
+- Dependencies or prerequisites not obvious from codebase
+- Breaking changes or migration concerns
+- Performance implications or best practices needed
+
+Example questions to ask:
+- "Should this cover MVVM integration or just basic XAML usage?"
+- "Are there Windows 11-specific features to document separately?"
+- "Is this replacing deprecated functionality? Should I note migration steps?"
+- "Should I document thread safety or async considerations?"
+
+Iterative Refinement:
+1. Present initial draft with core examples
+2. Ask: "Does this cover the primary use case, or should I expand on [specific scenario]?"
+3. Incorporate feedback and refine
+4. Verify technical accuracy by cross-referencing implementation
+5. Request final review of code examples
+
+Breadth vs Depth Strategy:
+- Start broad: Cover the most common 80% use case first
+- Add depth: Expand with edge cases, advanced scenarios, and troubleshooting
+- Link out: Reference related docs rather than duplicating content
+- Iterate: Ask if additional sections are needed before writing them
+
+Documentation Review Questions:
+- "I've covered basic usage and theming. Should I add sections on custom styling or performance optimization?"
+- "The current draft focuses on XAML. Do you need C# code-behind examples?"
+- "Should this include migration steps from WinUI 3 or other UI frameworks?"
+
+
+
+When creating documentation:
+1. Search codebase to understand implementation and API surface
+2. Identify primary use case and target audience
+3. Draft core content with minimal but complete examples
+4. Ask clarifying questions about scope and depth
+5. Iterate based on feedback
+6. Verify all code examples execute correctly
+7. Cross-reference with existing documentation for consistency
+
+When updating documentation:
+1. Identify what changed in the codebase
+2. Preserve existing structure and style
+3. Update only affected sections
+4. Ask if scope should expand to cover related changes
+5. Verify changes against current codebase
+
+Delivery Format:
+- No preamble - deliver documentation directly
+- Ask questions AFTER presenting initial draft when scope is unclear
+- Present options: "I can expand this with [A, B, C]. Which would be most valuable?"
+- Iterate quickly based on feedback
+
+
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 000000000..9af58d77e
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,179 @@
+You are an AI coding agent helping build WPF-UI, a modern WPF library implementing Microsoft Fluent UI design. This is an open-source library used by thousands of developers. Focus on the Wpf.Ui library itself, not the Gallery demo application.
+
+
+Core library location: src/Wpf.Ui/
+- Controls/ - NavigationView, TitleBar, FluentWindow, Button, Card, etc.
+- Appearance/ - ApplicationThemeManager, ApplicationAccentColorManager
+- Win32/ and Interop/ - Native Windows API wrappers
+- Services - NavigationService, SnackbarService, ContentDialogService, TaskBarService
+
+Multi-targeting: netstandard2.0/2.1, net462/472, net6.0/8.0/9.0 (see Directory.Build.props)
+Central Package Management: Directory.Packages.props - NEVER add package versions to .csproj files
+
+
+
+Build library:
+dotnet build src/Wpf.Ui/Wpf.Ui.csproj
+
+Solution filters:
+- Wpf.Ui.Library.slnf - Library projects only
+- Wpf.Ui.Gallery.slnf - Gallery demo app
+
+Testing:
+- XUnit v3 for unit tests (tests/Wpf.Ui.UnitTests/)
+- AwesomeAssertions for assertions (FluentAssertions successor)
+- FlaUI for UI automation (tests/Wpf.Ui.Gallery.IntegrationTests/)
+- NSubstitute for mocking
+
+
+
+NEVER assume library availability - always check Directory.Packages.props or .csproj first before using any external types.
+
+Modern C# (C# 13, LangVersion in Directory.Build.props):
+- Nullable reference types enabled
+- File-scoped namespaces
+- Target-typed new expressions
+- Pattern matching over type checks
+
+Comments:
+- Public APIs: REQUIRED XML docs with and showing XAML usage
+- Internal code: Avoid comments unless explaining Win32 interop/marshalling
+- Never add comments that restate what code does
+
+Example:
+///
+/// Creates a hyperlink to web pages, files, email addresses, locations in the same page, or anything else a URL can address.
+///
+///
+///
+/// <ui:Anchor NavigateUri="https://lepo.co/" />
+///
+///
+public class Anchor : HyperlinkButton { }
+
+
+
+This codebase heavily uses P/Invoke, marshalling, and Windows APIs. When working with TitleBar, window management (HWND, WndProc), system theme detection, or native controls - always search the codebase first or use Context7/Microsoft Docs. Do not assume standard WPF approaches work.
+
+Key interop areas:
+- src/Wpf.Ui/Win32/ - Native methods, structs, enums
+- src/Wpf.Ui/Interop/ - Managed wrappers
+- src/Wpf.Ui/Controls/TitleBar/ - Snap layouts, DWM integration
+- src/Wpf.Ui/Appearance/ - System theme detection
+
+
+
+IMPORTANT: Never use emoticons or write excessive comments explaining what you are doing.
+IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.
+IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
+Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations.
+
+
+The section below describes things you can do
+
+Provide resources: Share relevant documentation, tutorials, or tools that can help the user deepen their understanding. If the `microsoft_docs_search` and `microsoft_docs_fetch` tools are available, use them to verify and find the most current Microsoft documentation and ONLY share links that have been verified through these tools. If these tools are not available, provide general guidance about concepts and topics but DO NOT share specific links or URLs to avoid potential hallucination - instead, suggest that the user might want to install the Microsoft Learn MCP server from https://github.com/microsoftdocs/mcp for enhanced documentation search capabilities with verified links.
+
+
+When writing code, follow the best practices described below.
+
+Use modern C# syntax for .NET 10. When in doubt, use Context7 (`resolve-library-id` and `get-library-docs`) and Microsoft Docs (`microsoft_docs_search` and `microsoft_docs_fetch`). You can also use other MCP tools to find answers, e.g., search code with `search` or repository with `githubRepo`.
+
+Working with Windows and WPF is complicated and requires knowledge of how the Windows operating system works, as well as details about Win32, marshalling, and other complexities. Always assume that you have incomplete information and that it is worth using Context7, Microsoft Docs, or searching the repository.
+
+Remember to add summary docs with examples to each public class. Thousands of people use the framework and need proper instructions.
+
+```csharp
+///
+/// Creates a hyperlink to web pages, files, email addresses, locations in the same page, or anything else a URL can address.
+///
+///
+///
+/// <ui:Anchor
+/// NavigateUri="https://lepo.co/" />
+///
+///
+public class Anchor : Wpf.Ui.Controls.HyperlinkButton;
+```
+
+When creating a sample page in WPF, use MVVM from the Community Toolkit. Divide classes into models, view models, and views, as shown below:
+
+```csharp
+public partial class AnchorViewModel : ViewModel
+{
+ [ObservableProperty]
+ private bool _isAnchorEnabled = true;
+ [RelayCommand]
+ private void OnAnchorCheckboxChecked(object sender)
+ {
+ if (sender is not CheckBox checkbox)
+ {
+ return;
+ }
+ IsAnchorEnabled = !(checkbox?.IsChecked ?? false);
+ }
+}
+[GalleryPage("Button which opens a link.", SymbolRegular.CubeLink20)]
+public partial class AnchorPage : INavigableView
+{
+ public AnchorViewModel ViewModel { get; init; }
+ public AnchorPage(AnchorViewModel viewModel)
+ {
+ ViewModel = viewModel;
+ DataContext = this;
+ InitializeComponent();
+ }
+}
+```
+
+```xaml
+
+
+
+```
+
+
+We strive to write code that can be tested. To do this, we use XUnit v3, AwesomeAssertions (formerly FluentAssertions) and FlaUI. When we write unit tests, we write them as shown below.
+
+
+```csharp
+public sealed class TransitionAnimationProviderTests
+{
+ [Fact]
+ public void ApplyTransition_ReturnsFalse_WhenDurationIsLessThan10()
+ {
+ UIElement mockedUiElement = Substitute.For();
+ var result = TransitionAnimationProvider.ApplyTransition(mockedUiElement, Transition.FadeIn, -10);
+ result.Should().BeFalse();
+ }
+}
+```
+
+When we write integration tests, we write them as shown below.
+
+```csharp
+public sealed class TitleBarTests : UiTest
+{
+ [Fact]
+ public async Task CloseButton_ShouldCloseWindow_WhenClicked()
+ {
+ Button? closeButton = FindFirst("TitleBarCloseButton").AsButton();
+
+ closeButton.Should().NotBeNull("because CloseButton should be present in the main window title bar");
+ closeButton.Click(moveMouse: false);
+
+ await Wait(2);
+
+ Application
+ ?.HasExited.Should()
+ .BeTrue("because the main window should be closed after clicking the close button");
+ }
+}
+```
+
diff --git a/.github/workflows/top-issues-dashboard.yml b/.github/workflows/top-issues-dashboard.yml
new file mode 100644
index 000000000..f1c3ffbf6
--- /dev/null
+++ b/.github/workflows/top-issues-dashboard.yml
@@ -0,0 +1,24 @@
+name: wpf-ui-top-issues-dashboard
+on:
+ schedule:
+ - cron: '0 0 */1 * *'
+
+jobs:
+ ShowAndLabelTopIssues:
+ name: Display and label top issues.
+ runs-on: ubuntu-latest
+ steps:
+ - name: Top Issues action
+ uses: rickstaa/top-issues-action@v1.3.101
+ env:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ top_list_size: 10
+ label: true
+ dashboard: true
+ dashboard_show_total_reactions: true
+ top_issues: true
+ top_bugs: true
+ top_features: true
+ feature_label: feature
+ top_pull_requests: true
diff --git a/.github/workflows/wpf-ui-cd-docs.yaml b/.github/workflows/wpf-ui-cd-docs.yaml
index f6b39b482..ba0368dcf 100644
--- a/.github/workflows/wpf-ui-cd-docs.yaml
+++ b/.github/workflows/wpf-ui-cd-docs.yaml
@@ -33,10 +33,10 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 18.x
- - name: Setup .NET Core SDK 8.x
+ - name: Setup .NET Core SDK 10.x
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: 10.x
- name: Install docfx
run: dotnet tool update -g docfx
diff --git a/.github/workflows/wpf-ui-cd-extension.yaml b/.github/workflows/wpf-ui-cd-extension.yaml
index 6e01ee14a..8cfe5caa4 100644
--- a/.github/workflows/wpf-ui-cd-extension.yaml
+++ b/.github/workflows/wpf-ui-cd-extension.yaml
@@ -4,7 +4,7 @@ on:
push:
branches: [main]
paths:
- - 'src/Wpf.Ui.Extension**`
+ - 'src/Wpf.Ui.Extension**'
workflow_dispatch:
@@ -16,6 +16,11 @@ jobs:
- uses: microsoft/setup-msbuild@v2
with:
msbuild-architecture: x64
+ - name: Setup .NET Core SDK 10.x
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: 10.x
+
- uses: nuget/setup-nuget@v2
with:
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
@@ -24,9 +29,17 @@ jobs:
run: nuget restore Wpf.Ui.sln
- name: Build the solution
- run: msbuild src\Wpf.Ui.Extension\Wpf.Ui.Extension.csproj /t:Rebuild -p:Configuration=Release -p:RestorePackages=false -p:Platform="x64" -p:GITHUB_ACTIONS=True
+ run: msbuild src\Wpf.Ui.Extension\Wpf.Ui.Extension.csproj /t:Rebuild -p:Configuration=Release -p:RestorePackages=false -p:Platform="x64" -p:ProductArchitecture="amd64" -p:GITHUB_ACTIONS=True -p:LangVersion=8.0
+
+ - name: Build the solution
+ run: msbuild src\Wpf.Ui.Extension\Wpf.Ui.Extension.csproj /t:Rebuild -p:Configuration=Release -p:RestorePackages=false -p:Platform="arm64" -p:ProductArchitecture="arm64" -p:GITHUB_ACTIONS=True -p:LangVersion=8.0
- uses: actions/upload-artifact@v4
with:
- name: wpf-ui-vs22-extension
+ name: wpf-ui-vs22-extension-x64
path: src\Wpf.Ui.Extension\bin\x64\Release\Wpf.Ui.Extension.vsix
+
+ - uses: actions/upload-artifact@v4
+ with:
+ name: wpf-ui-vs22-extension-arm64
+ path: src\Wpf.Ui.Extension\bin\arm64\Release\Wpf.Ui.Extension.vsix
diff --git a/.github/workflows/wpf-ui-cd-nuget.yaml b/.github/workflows/wpf-ui-cd-nuget.yaml
index 4c19d45ea..6af161ed3 100644
--- a/.github/workflows/wpf-ui-cd-nuget.yaml
+++ b/.github/workflows/wpf-ui-cd-nuget.yaml
@@ -2,7 +2,11 @@ name: wpf-ui-cd-nuget
on:
push:
- branches: [main]
+ branches:
+ - main
+ - release/*
+ paths:
+ - 'src/**'
workflow_dispatch:
@@ -17,10 +21,17 @@ jobs:
- uses: nuget/setup-nuget@v2
with:
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
- - name: Setup .NET Core SDK 8.x
+ - name: Setup .NET Core SDK 10.x
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: 10.x
+
+ - name: Fetch the certificate
+ run: |
+ $signing_keys_payload = [System.Convert]::FromBase64String("${{ secrets.STRONG_NAME_KEY }}")
+ $currentDirectory = Get-Location
+ $certificatePath = Join-Path -Path $currentDirectory -ChildPath "src/lepo.snk"
+ [IO.File]::WriteAllBytes("$certificatePath", $signing_keys_payload)
- name: Install dependencies
run: dotnet restore
@@ -31,11 +42,22 @@ jobs:
- name: Build
run: dotnet build src\Wpf.Ui.Abstractions\Wpf.Ui.Abstractions.csproj --configuration Release --no-restore -p:SourceLinkEnabled=true
+ - name: Build
+ run: dotnet build src\Wpf.Ui.DependencyInjection\Wpf.Ui.DependencyInjection.csproj --configuration Release --no-restore -p:SourceLinkEnabled=true
+
- name: Build
run: dotnet build src\Wpf.Ui.Tray\Wpf.Ui.Tray.csproj --configuration Release --no-restore -p:SourceLinkEnabled=true
- name: Publish the package to NuGet.org
+ continue-on-error: true
run: nuget push **\*.nupkg -NonInteractive -SkipDuplicate -Source 'https://api.nuget.org/v3/index.json'
- name: Publish the symbols to NuGet.org
+ continue-on-error: true
run: nuget push **\*.snupkg -NonInteractive -SkipDuplicate -Source 'https://api.nuget.org/v3/index.json'
+
+ - name: Upload NuGet packages as artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: nuget-packages
+ path: '**\*.nupkg'
diff --git a/.github/workflows/wpf-ui-lock.yml b/.github/workflows/wpf-ui-lock.yml
index e47736a27..3cd32bf28 100644
--- a/.github/workflows/wpf-ui-lock.yml
+++ b/.github/workflows/wpf-ui-lock.yml
@@ -2,7 +2,7 @@ name: wpf-ui-lock
on:
schedule:
- - cron: '0 * * * *'
+ - cron: '0 0 * * 0'
workflow_dispatch:
permissions:
diff --git a/.github/workflows/wpf-ui-pr-validator.yaml b/.github/workflows/wpf-ui-pr-validator.yaml
index c2e4fa698..28323af9f 100644
--- a/.github/workflows/wpf-ui-pr-validator.yaml
+++ b/.github/workflows/wpf-ui-pr-validator.yaml
@@ -17,10 +17,10 @@ jobs:
- uses: nuget/setup-nuget@v2
with:
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
- - name: Setup .NET Core SDK 8.x
+ - name: Setup .NET Core SDK 10.x
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: 10.x
- name: Install dependencies
run: dotnet restore
diff --git a/.gitignore b/.gitignore
index e628c2e8c..30b97c438 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,9 +2,15 @@
## files generated by popular Visual Studio add-ons.
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+# Strong Name Key files
+src/lepo.snk
+
# DocFX
docs/api/
+# Desktop service store
+.DS_Store
+
# User-specific files
*.rsuser
*.suo
diff --git a/Directory.Build.props b/Directory.Build.props
index f41b3dcea..573a58be1 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,14 +1,12 @@
-
$(MSBuildThisFileDirectory)
$(RepositoryDirectory)build\
-
- 4.0.0-rc.1
+ 4.1.0
+ 4.1.0
-
lepo.co
lepo.co
@@ -16,7 +14,7 @@
lepoco;toolkit;wpf;fluent;navigation;controls;design;icons;system;accent;theme;winui
MIT
true
- Copyright (C) 2021-2024 Leszek Pomianowski and WPF UI Contributors
+ Copyright (C) 2021-2025 Leszek Pomianowski and WPF UI Contributors
https://github.com/lepoco/wpfui
https://github.com/lepoco/wpfui/releases
Icon.png
@@ -24,25 +22,24 @@
main
git
-
+
+
+
true
moderate
true
false
true
+ <_SilenceIsAotCompatibleUnsupportedWarning>true
-
true
- true
-
true
- 12.0
+ 14.0
enable
-
$(NoWarn);CS8500
-
$(MSBuildProjectName.Contains('Test'))
False
True
+ True
-
-
-
-
-
+
+ true
+ true
+ $(TF_BUILD)
+
+
+ $(DefineConstants);NET8_0_OR_GREATER
+
+
+
+
+ README.md
+ true
+
+
+
+
+ false
+ false
+ $(NoWarn);CS8002;SA0001
+
+
+
-
+
true
@@ -76,5 +104,4 @@
-
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 8a271aa74..fec00b0d4 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,90 +1,88 @@
-
true
-
$(CommonTags);.NET
$(CommonTags);$(PackageTags)
$(CommonTags)
-
true
README.md
- false
+ true
true
snupkg
true
true
-
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ build; analyzers
+
+
+ all
+ build; analyzers
+
+
+ all
+ build; analyzers
+
+
+ all
+ build; analyzers
+
+
+ all
+ build; analyzers
+
+
-
+
<_Parameter1>CommitHash
<_Parameter2>$(SourceRevisionId)
-
-
+
true
true
true
true
-
-
-
- $(IntermediateOutputPath)$(MSBuildProjectName).SkipLocalsInit.g.cs
-
-
-// This code was generated by a tool.
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-[module: global::System.Runtime.CompilerServices.SkipLocalsInitAttribute]]]>
-
+
+ true
+ $(RepositoryDirectory)\src\lepo.snk
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PerMonitor
+ true/PM
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/applicationIcon.ico b/samples/Wpf.Ui.Demo.SetResources.Simple/applicationIcon.ico
new file mode 100644
index 000000000..cc128fda3
Binary files /dev/null and b/samples/Wpf.Ui.Demo.SetResources.Simple/applicationIcon.ico differ
diff --git a/samples/Wpf.Ui.Demo.Simple/App.xaml b/samples/Wpf.Ui.Demo.Simple/App.xaml
index d57167c26..fae622c78 100644
--- a/samples/Wpf.Ui.Demo.Simple/App.xaml
+++ b/samples/Wpf.Ui.Demo.Simple/App.xaml
@@ -1,15 +1,16 @@
-
-
-
-
-
-
-
-
+ x:Class="Wpf.Ui.Demo.Simple.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ StartupUri="MainWindow.xaml"
+>
+
+
+
+
+
+
+
+
diff --git a/samples/Wpf.Ui.Demo.Simple/MainWindow.xaml b/samples/Wpf.Ui.Demo.Simple/MainWindow.xaml
index 4d430b511..ba09c4e6e 100644
--- a/samples/Wpf.Ui.Demo.Simple/MainWindow.xaml
+++ b/samples/Wpf.Ui.Demo.Simple/MainWindow.xaml
@@ -1,100 +1,99 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ x:Class="Wpf.Ui.Demo.Simple.MainWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Wpf.Ui.Demo.Simple"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:pages="clr-namespace:Wpf.Ui.Demo.Simple.Views.Pages"
+ xmlns:tray="http://schemas.lepo.co/wpfui/2022/xaml/tray"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ Title="WPF UI - Simple Demo"
+ Width="1100"
+ Height="650"
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ ExtendsContentIntoTitleBar="True"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ WindowBackdropType="Mica"
+ WindowCornerPreference="Round"
+ WindowStartupLocation="CenterScreen"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Wpf.Ui.Demo.Simple/Views/Pages/DashboardPage.xaml b/samples/Wpf.Ui.Demo.Simple/Views/Pages/DashboardPage.xaml
index 55ec01c94..009d1729c 100644
--- a/samples/Wpf.Ui.Demo.Simple/Views/Pages/DashboardPage.xaml
+++ b/samples/Wpf.Ui.Demo.Simple/Views/Pages/DashboardPage.xaml
@@ -1,34 +1,30 @@
-
-
-
-
-
-
-
-
-
-
+ x:Class="Wpf.Ui.Demo.Simple.Views.Pages.DashboardPage"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Wpf.Ui.Demo.Simple.Views.Pages"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ Title="DashboardPage"
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
diff --git a/samples/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml b/samples/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml
index bc5ccbedb..f3361347a 100644
--- a/samples/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml
+++ b/samples/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml
@@ -1,41 +1,43 @@
-
-
-
-
-
-
-
-
-
-
+ x:Class="Wpf.Ui.Demo.Simple.Views.Pages.DataPage"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Wpf.Ui.Demo.Simple.Views.Pages"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:models="clr-namespace:Wpf.Ui.Demo.Simple.Models"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ Title="DataPage"
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ ScrollViewer.CanContentScroll="False"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
+
diff --git a/samples/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml.cs b/samples/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml.cs
index 99dc09c0b..dcc623b84 100644
--- a/samples/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml.cs
+++ b/samples/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml.cs
@@ -41,7 +41,7 @@ private void InitializeData()
(byte)random.Next(0, 250),
(byte)random.Next(0, 250)
)
- )
+ ),
}
);
}
diff --git a/samples/Wpf.Ui.Demo.Simple/Views/Pages/SettingsPage.xaml b/samples/Wpf.Ui.Demo.Simple/Views/Pages/SettingsPage.xaml
index a3b2817b8..f208757f2 100644
--- a/samples/Wpf.Ui.Demo.Simple/Views/Pages/SettingsPage.xaml
+++ b/samples/Wpf.Ui.Demo.Simple/Views/Pages/SettingsPage.xaml
@@ -1,44 +1,37 @@
īģŋ
-
-
-
-
-
-
-
-
-
-
-
+ x:Class="Wpf.Ui.Demo.Simple.Views.Pages.SettingsPage"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Wpf.Ui.Demo.Simple.Views.Pages"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ Title="SettingsPage"
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
diff --git a/samples/Wpf.Ui.Demo.Simple/Wpf.Ui.Demo.Simple.csproj b/samples/Wpf.Ui.Demo.Simple/Wpf.Ui.Demo.Simple.csproj
index ea1f29ef8..3fd6b162a 100644
--- a/samples/Wpf.Ui.Demo.Simple/Wpf.Ui.Demo.Simple.csproj
+++ b/samples/Wpf.Ui.Demo.Simple/Wpf.Ui.Demo.Simple.csproj
@@ -2,12 +2,11 @@
WinExe
- net8.0-windows10.0.22621.0
+ net10.0-windows10.0.26100.0
10.0.17763.0
true
app.manifest
applicationIcon.ico
- AnyCPU;x64
$(NoWarn);SA1601
diff --git a/src/Wpf.Ui.Abstractions/Controls/INavigationAware.cs b/src/Wpf.Ui.Abstractions/Controls/INavigationAware.cs
index 8843b52cb..8f9a087cb 100644
--- a/src/Wpf.Ui.Abstractions/Controls/INavigationAware.cs
+++ b/src/Wpf.Ui.Abstractions/Controls/INavigationAware.cs
@@ -14,7 +14,6 @@ public interface INavigationAware
/// Asynchronously handles the event that is fired after the component is navigated to.
///
/// A task that represents the asynchronous operation.
-
Task OnNavigatedToAsync();
///
diff --git a/src/Wpf.Ui.Abstractions/NavigationException.cs b/src/Wpf.Ui.Abstractions/NavigationException.cs
index ccf3b9981..c1d46e44f 100644
--- a/src/Wpf.Ui.Abstractions/NavigationException.cs
+++ b/src/Wpf.Ui.Abstractions/NavigationException.cs
@@ -11,14 +11,15 @@ namespace Wpf.Ui.Abstractions;
public sealed class NavigationException : Exception
{
///
- /// Initializes a new instance of the NavigationException class with a specified error message.
+ /// Initializes a new instance of the class with a specified error message.
///
/// The message that describes the error.
public NavigationException(string message)
: base(message) { }
///
- /// Initializes a new instance of the NavigationException class with a specified error message and a reference to the inner exception that is the cause of this exception.
+ /// 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.
///
/// The exception that is the cause of the current exception.
/// The message that describes the error.
diff --git a/src/Wpf.Ui.Abstractions/Wpf.Ui.Abstractions.csproj b/src/Wpf.Ui.Abstractions/Wpf.Ui.Abstractions.csproj
index 462d23eb9..8b578d989 100644
--- a/src/Wpf.Ui.Abstractions/Wpf.Ui.Abstractions.csproj
+++ b/src/Wpf.Ui.Abstractions/Wpf.Ui.Abstractions.csproj
@@ -2,21 +2,11 @@
WPF-UI.Abstractions
- netstandard2.0;netstandard2.1;net462;net6.0;net8.0
+ net10.0;net9.0;net8.0;net462;netstandard2.1;netstandard2.0
true
Abstractions for the WPF UI.
$(CommonTags);abstractions;standard
+ <_SilenceIsAotCompatibleUnsupportedWarning>true
-
-
- all
- build; analyzers
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
diff --git a/src/Wpf.Ui.DependencyInjection/ServiceCollectionExtensions.cs b/src/Wpf.Ui.DependencyInjection/ServiceCollectionExtensions.cs
index 71a7be708..1d9264743 100644
--- a/src/Wpf.Ui.DependencyInjection/ServiceCollectionExtensions.cs
+++ b/src/Wpf.Ui.DependencyInjection/ServiceCollectionExtensions.cs
@@ -18,7 +18,6 @@ public static class ServiceCollectionExtensions
///
/// The to add the services to.
/// The so that additional calls can be chained.
-
public static IServiceCollection AddNavigationViewPageProvider(this IServiceCollection services)
{
_ = services.AddSingleton<
diff --git a/src/Wpf.Ui.DependencyInjection/Wpf.Ui.DependencyInjection.csproj b/src/Wpf.Ui.DependencyInjection/Wpf.Ui.DependencyInjection.csproj
index 77003a0ac..1629d6223 100644
--- a/src/Wpf.Ui.DependencyInjection/Wpf.Ui.DependencyInjection.csproj
+++ b/src/Wpf.Ui.DependencyInjection/Wpf.Ui.DependencyInjection.csproj
@@ -2,26 +2,19 @@
WPF-UI.DependencyInjection
- netstandard2.0;netstandard2.1;net462;net6.0;net8.0
+ net10.0;net9.0;net8.0;net462;netstandard2.1;netstandard2.0
true
Dependency injection for the WPF UI.
$(CommonTags);dependency;injection;abstractions;standard
+ <_SilenceIsAotCompatibleUnsupportedWarning>true
-
- all
- build; analyzers
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
\ No newline at end of file
+
diff --git a/src/Wpf.Ui.Extension.Template.Blank/App.xaml b/src/Wpf.Ui.Extension.Template.Blank/App.xaml
index ed1ed0c52..3ac11ba34 100644
--- a/src/Wpf.Ui.Extension.Template.Blank/App.xaml
+++ b/src/Wpf.Ui.Extension.Template.Blank/App.xaml
@@ -1,17 +1,18 @@
īģŋ
-
-
-
-
-
-
-
-
+ x:Class="$safeprojectname$.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ DispatcherUnhandledException="OnDispatcherUnhandledException"
+ Exit="OnExit"
+ Startup="OnStartup"
+>
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Blank/App.xaml.cs b/src/Wpf.Ui.Extension.Template.Blank/App.xaml.cs
index 2f88101a2..c61e08387 100644
--- a/src/Wpf.Ui.Extension.Template.Blank/App.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Blank/App.xaml.cs
@@ -27,22 +27,19 @@ public partial class App
}).Build();
///
- /// Gets registered service.
+ /// Gets services.
///
- /// Type of the service to get.
- /// Instance of the service or .
- public static T GetService()
- where T : class
+ public static IServiceProvider Services
{
- return _host.Services.GetService(typeof(T)) as T;
+ get { return _host.Services; }
}
///
/// Occurs when the application is loading.
///
- private void OnStartup(object sender, StartupEventArgs e)
+ private async void OnStartup(object sender, StartupEventArgs e)
{
- _host.Start();
+ await _host.StartAsync();
}
///
diff --git a/src/Wpf.Ui.Extension.Template.Blank/Wpf.Ui.Blank.csproj b/src/Wpf.Ui.Extension.Template.Blank/Wpf.Ui.Blank.csproj
index 10e0f486b..9eb338561 100644
--- a/src/Wpf.Ui.Extension.Template.Blank/Wpf.Ui.Blank.csproj
+++ b/src/Wpf.Ui.Extension.Template.Blank/Wpf.Ui.Blank.csproj
@@ -2,7 +2,7 @@
WinExe
- net8.0-windows
+ net10.0-windows
app.manifest
wpfui-icon.ico
true
@@ -15,9 +15,10 @@
-
-
-
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Blank/Wpf.Ui.Extension.Template.Blank.csproj b/src/Wpf.Ui.Extension.Template.Blank/Wpf.Ui.Extension.Template.Blank.csproj
index 713964ea9..880845b06 100644
--- a/src/Wpf.Ui.Extension.Template.Blank/Wpf.Ui.Extension.Template.Blank.csproj
+++ b/src/Wpf.Ui.Extension.Template.Blank/Wpf.Ui.Extension.Template.Blank.csproj
@@ -1,7 +1,7 @@
īģŋ
-
+
+ true
17.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
@@ -10,6 +10,16 @@
15.0
+ win;win-x64;win-arm64
+ 8.0
+
+
+ true
+ bin\Debug\
+ DEBUG;TRACE
+ full
+ 11.0
+ prompt
true
@@ -20,6 +30,23 @@
11.0
prompt
+
+ true
+ bin\arm64\Debug\
+ DEBUG;TRACE
+ full
+ arm64
+ 11.0
+ prompt
+
+
+ bin\Release\
+ TRACE
+ true
+ pdbonly
+ 11.0
+ prompt
+
bin\x64\Release\
TRACE
@@ -29,17 +56,26 @@
11.0
prompt
+
+ bin\arm64\Release\
+ TRACE
+ true
+ pdbonly
+ arm64
+ 11.0
+ prompt
+
Debug
AnyCPU
{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {ab3d44b5-9491-487e-a134-9ac5bed2b981}
+ {AB3D44B5-9491-487E-A134-9AC5BED2B981}
Library
Properties
Wpf.Ui.Extension.Template.Blank
Wpf.Ui.Extension.Template.Blank
- v4.8
+ v4.8.1
false
false
false
diff --git a/src/Wpf.Ui.Extension.Template.Compact/App.xaml b/src/Wpf.Ui.Extension.Template.Compact/App.xaml
index ed37ef0f3..d8d4c2e32 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/App.xaml
+++ b/src/Wpf.Ui.Extension.Template.Compact/App.xaml
@@ -1,17 +1,18 @@
īģŋ
-
-
-
-
-
-
-
-
+ x:Class="$safeprojectname$.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ DispatcherUnhandledException="OnDispatcherUnhandledException"
+ Exit="OnExit"
+ Startup="OnStartup"
+>
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Compact/App.xaml.cs b/src/Wpf.Ui.Extension.Template.Compact/App.xaml.cs
index 5e3346fdd..551f4e925 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/App.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Compact/App.xaml.cs
@@ -10,6 +10,7 @@
using $safeprojectname$.Views.Pages;
using $safeprojectname$.Views.Windows;
using Wpf.Ui;
+using Wpf.Ui.DependencyInjection;
namespace $safeprojectname$
{
@@ -28,10 +29,9 @@ public partial class App
.ConfigureAppConfiguration(c => { c.SetBasePath(Path.GetDirectoryName(AppContext.BaseDirectory)); })
.ConfigureServices((context, services) =>
{
- services.AddHostedService();
+ services.AddNavigationViewPageProvider();
- // Page resolver service
- services.AddSingleton();
+ services.AddHostedService();
// Theme manipulation
services.AddSingleton();
@@ -55,22 +55,19 @@ public partial class App
}).Build();
///
- /// Gets registered service.
+ /// Gets services.
///
- /// Type of the service to get.
- /// Instance of the service or .
- public static T GetService()
- where T : class
+ public static IServiceProvider Services
{
- return _host.Services.GetService(typeof(T)) as T;
+ get { return _host.Services; }
}
///
/// Occurs when the application is loading.
///
- private void OnStartup(object sender, StartupEventArgs e)
+ private async void OnStartup(object sender, StartupEventArgs e)
{
- _host.Start();
+ await _host.StartAsync();
}
///
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Services/PageService.cs b/src/Wpf.Ui.Extension.Template.Compact/Services/PageService.cs
deleted file mode 100644
index 2578f166d..000000000
--- a/src/Wpf.Ui.Extension.Template.Compact/Services/PageService.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Wpf.Ui;
-
-namespace $safeprojectname$.Services
-{
- ///
- /// Service that provides pages for navigation.
- ///
- public class PageService : IPageService
- {
- ///
- /// Service which provides the instances of pages.
- ///
- private readonly IServiceProvider _serviceProvider;
-
- ///
- /// Creates new instance and attaches the .
- ///
- public PageService(IServiceProvider serviceProvider)
- {
- _serviceProvider = serviceProvider;
- }
-
- ///
- public T? GetPage()
- where T : class
- {
- if (!typeof(FrameworkElement).IsAssignableFrom(typeof(T)))
- throw new InvalidOperationException("The page should be a WPF control.");
-
- return (T?)_serviceProvider.GetService(typeof(T));
- }
-
- ///
- public FrameworkElement? GetPage(Type pageType)
- {
- if (!typeof(FrameworkElement).IsAssignableFrom(pageType))
- throw new InvalidOperationException("The page should be a WPF control.");
-
- return _serviceProvider.GetService(pageType) as FrameworkElement;
- }
- }
-}
diff --git a/src/Wpf.Ui.Extension.Template.Compact/ViewModels/Pages/DataViewModel.cs b/src/Wpf.Ui.Extension.Template.Compact/ViewModels/Pages/DataViewModel.cs
index 449dcf9c7..fc5225155 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/ViewModels/Pages/DataViewModel.cs
+++ b/src/Wpf.Ui.Extension.Template.Compact/ViewModels/Pages/DataViewModel.cs
@@ -1,6 +1,6 @@
īģŋusing System.Windows.Media;
using $safeprojectname$.Models;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.ViewModels.Pages
{
@@ -11,13 +11,15 @@ public partial class DataViewModel : ObservableObject, INavigationAware
[ObservableProperty]
private IEnumerable _colors;
- public void OnNavigatedTo()
+ public Task OnNavigatedToAsync()
{
if (!_isInitialized)
InitializeViewModel();
+
+ return Task.CompletedTask;
}
- public void OnNavigatedFrom() { }
+ public Task OnNavigatedFromAsync() => Task.CompletedTask;
private void InitializeViewModel()
{
diff --git a/src/Wpf.Ui.Extension.Template.Compact/ViewModels/Pages/SettingsViewModel.cs b/src/Wpf.Ui.Extension.Template.Compact/ViewModels/Pages/SettingsViewModel.cs
index 2d0224df3..1a743f36e 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/ViewModels/Pages/SettingsViewModel.cs
+++ b/src/Wpf.Ui.Extension.Template.Compact/ViewModels/Pages/SettingsViewModel.cs
@@ -1,5 +1,5 @@
īģŋusing Wpf.Ui.Appearance;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.ViewModels.Pages
{
@@ -13,13 +13,15 @@ public partial class SettingsViewModel : ObservableObject, INavigationAware
[ObservableProperty]
private ApplicationTheme _currentTheme = ApplicationTheme.Unknown;
- public void OnNavigatedTo()
+ public Task OnNavigatedToAsync()
{
if (!_isInitialized)
InitializeViewModel();
+
+ return Task.CompletedTask;
}
- public void OnNavigatedFrom() { }
+ public Task OnNavigatedFromAsync() => Task.CompletedTask;
private void InitializeViewModel()
{
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DashboardPage.xaml b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DashboardPage.xaml
index 0cf585792..91b9bd841 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DashboardPage.xaml
+++ b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DashboardPage.xaml
@@ -1,36 +1,37 @@
īģŋ
-
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DashboardPage.xaml.cs b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DashboardPage.xaml.cs
index 288b6feeb..97a97382d 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DashboardPage.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DashboardPage.xaml.cs
@@ -1,5 +1,5 @@
īģŋusing $safeprojectname$.ViewModels.Pages;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.Views.Pages
{
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DataPage.xaml b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DataPage.xaml
index 6268e0521..b745bb0f3 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DataPage.xaml
+++ b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DataPage.xaml
@@ -1,43 +1,45 @@
-
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ ScrollViewer.CanContentScroll="False"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DataPage.xaml.cs b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DataPage.xaml.cs
index 5c0fa3e89..566af09d4 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DataPage.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/DataPage.xaml.cs
@@ -1,5 +1,5 @@
īģŋusing $safeprojectname$.ViewModels.Pages;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.Views.Pages
{
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/SettingsPage.xaml b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/SettingsPage.xaml
index d0c1e49a8..06626db7e 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/SettingsPage.xaml
+++ b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/SettingsPage.xaml
@@ -1,51 +1,45 @@
īģŋ
-
-
-
-
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/SettingsPage.xaml.cs b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/SettingsPage.xaml.cs
index c3decb5af..ee4559d8f 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/SettingsPage.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Compact/Views/Pages/SettingsPage.xaml.cs
@@ -1,5 +1,5 @@
īģŋusing $safeprojectname$.ViewModels.Pages;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.Views.Pages
{
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Views/Windows/MainWindow.xaml b/src/Wpf.Ui.Extension.Template.Compact/Views/Windows/MainWindow.xaml
index 56ac1e0fe..5dae97a0b 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Views/Windows/MainWindow.xaml
+++ b/src/Wpf.Ui.Extension.Template.Compact/Views/Windows/MainWindow.xaml
@@ -1,75 +1,76 @@
īģŋ
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ ExtendsContentIntoTitleBar="True"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ WindowBackdropType="Mica"
+ WindowCornerPreference="Round"
+ WindowStartupLocation="CenterScreen"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Views/Windows/MainWindow.xaml.cs b/src/Wpf.Ui.Extension.Template.Compact/Views/Windows/MainWindow.xaml.cs
index 5e09543d8..8c138073b 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Views/Windows/MainWindow.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Compact/Views/Windows/MainWindow.xaml.cs
@@ -1,5 +1,6 @@
īģŋusing $safeprojectname$.ViewModels.Windows;
using Wpf.Ui;
+using Wpf.Ui.Abstractions;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
@@ -11,7 +12,7 @@ public partial class MainWindow : INavigationWindow
public MainWindow(
MainWindowViewModel viewModel,
- IPageService pageService,
+ INavigationViewPageProvider navigationViewPageProvider,
INavigationService navigationService
)
{
@@ -21,7 +22,7 @@ INavigationService navigationService
SystemThemeWatcher.Watch(this);
InitializeComponent();
- SetPageService(pageService);
+ SetPageService(navigationViewPageProvider);
navigationService.SetNavigationControl(RootNavigation);
}
@@ -32,7 +33,7 @@ INavigationService navigationService
public bool Navigate(Type pageType) => RootNavigation.Navigate(pageType);
- public void SetPageService(IPageService pageService) => RootNavigation.SetPageService(pageService);
+ public void SetPageService(INavigationViewPageProvider navigationViewPageProvider) => RootNavigation.SetPageProviderService(navigationViewPageProvider);
public void ShowWindow() => Show();
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Compact.csproj b/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Compact.csproj
index 10e0f486b..9eb338561 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Compact.csproj
+++ b/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Compact.csproj
@@ -2,7 +2,7 @@
WinExe
- net8.0-windows
+ net10.0-windows
app.manifest
wpfui-icon.ico
true
@@ -15,9 +15,10 @@
-
-
-
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Compact.vstemplate b/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Compact.vstemplate
index 3ccb210be..375ae28d9 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Compact.vstemplate
+++ b/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Compact.vstemplate
@@ -39,7 +39,6 @@
ApplicationHostService.cs
- PageService.cs
diff --git a/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Extension.Template.Compact.csproj b/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Extension.Template.Compact.csproj
index 2fe233473..7d3005c5c 100644
--- a/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Extension.Template.Compact.csproj
+++ b/src/Wpf.Ui.Extension.Template.Compact/Wpf.Ui.Extension.Template.Compact.csproj
@@ -1,7 +1,7 @@
īģŋ
-
+
+ true
17.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
@@ -10,6 +10,16 @@
15.0
+ win;win-x64;win-arm64
+ 8.0
+
+
+ true
+ bin\Debug\
+ DEBUG;TRACE
+ full
+ 11.0
+ prompt
true
@@ -20,6 +30,23 @@
11.0
prompt
+
+ true
+ bin\arm64\Debug\
+ DEBUG;TRACE
+ full
+ arm64
+ 11.0
+ prompt
+
+
+ bin\Release\
+ TRACE
+ true
+ pdbonly
+ 11.0
+ prompt
+
bin\x64\Release\
TRACE
@@ -29,6 +56,15 @@
11.0
prompt
+
+ bin\arm64\Release\
+ TRACE
+ true
+ pdbonly
+ arm64
+ 11.0
+ prompt
+
Debug
@@ -39,7 +75,7 @@
Properties
Wpf.Ui.Extension.Template.Compact
Wpf.Ui.Extension.Template.Compact
- v4.8
+ v4.8.1
false
false
false
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/App.xaml b/src/Wpf.Ui.Extension.Template.Fluent/App.xaml
index ed37ef0f3..d8d4c2e32 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/App.xaml
+++ b/src/Wpf.Ui.Extension.Template.Fluent/App.xaml
@@ -1,17 +1,18 @@
īģŋ
-
-
-
-
-
-
-
-
+ x:Class="$safeprojectname$.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ DispatcherUnhandledException="OnDispatcherUnhandledException"
+ Exit="OnExit"
+ Startup="OnStartup"
+>
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/App.xaml.cs b/src/Wpf.Ui.Extension.Template.Fluent/App.xaml.cs
index 5e3346fdd..551f4e925 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/App.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Fluent/App.xaml.cs
@@ -10,6 +10,7 @@
using $safeprojectname$.Views.Pages;
using $safeprojectname$.Views.Windows;
using Wpf.Ui;
+using Wpf.Ui.DependencyInjection;
namespace $safeprojectname$
{
@@ -28,10 +29,9 @@ public partial class App
.ConfigureAppConfiguration(c => { c.SetBasePath(Path.GetDirectoryName(AppContext.BaseDirectory)); })
.ConfigureServices((context, services) =>
{
- services.AddHostedService();
+ services.AddNavigationViewPageProvider();
- // Page resolver service
- services.AddSingleton();
+ services.AddHostedService();
// Theme manipulation
services.AddSingleton();
@@ -55,22 +55,19 @@ public partial class App
}).Build();
///
- /// Gets registered service.
+ /// Gets services.
///
- /// Type of the service to get.
- /// Instance of the service or .
- public static T GetService()
- where T : class
+ public static IServiceProvider Services
{
- return _host.Services.GetService(typeof(T)) as T;
+ get { return _host.Services; }
}
///
/// Occurs when the application is loading.
///
- private void OnStartup(object sender, StartupEventArgs e)
+ private async void OnStartup(object sender, StartupEventArgs e)
{
- _host.Start();
+ await _host.StartAsync();
}
///
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Services/PageService.cs b/src/Wpf.Ui.Extension.Template.Fluent/Services/PageService.cs
deleted file mode 100644
index 2578f166d..000000000
--- a/src/Wpf.Ui.Extension.Template.Fluent/Services/PageService.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Wpf.Ui;
-
-namespace $safeprojectname$.Services
-{
- ///
- /// Service that provides pages for navigation.
- ///
- public class PageService : IPageService
- {
- ///
- /// Service which provides the instances of pages.
- ///
- private readonly IServiceProvider _serviceProvider;
-
- ///
- /// Creates new instance and attaches the .
- ///
- public PageService(IServiceProvider serviceProvider)
- {
- _serviceProvider = serviceProvider;
- }
-
- ///
- public T? GetPage()
- where T : class
- {
- if (!typeof(FrameworkElement).IsAssignableFrom(typeof(T)))
- throw new InvalidOperationException("The page should be a WPF control.");
-
- return (T?)_serviceProvider.GetService(typeof(T));
- }
-
- ///
- public FrameworkElement? GetPage(Type pageType)
- {
- if (!typeof(FrameworkElement).IsAssignableFrom(pageType))
- throw new InvalidOperationException("The page should be a WPF control.");
-
- return _serviceProvider.GetService(pageType) as FrameworkElement;
- }
- }
-}
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/ViewModels/Pages/DataViewModel.cs b/src/Wpf.Ui.Extension.Template.Fluent/ViewModels/Pages/DataViewModel.cs
index 449dcf9c7..fc5225155 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/ViewModels/Pages/DataViewModel.cs
+++ b/src/Wpf.Ui.Extension.Template.Fluent/ViewModels/Pages/DataViewModel.cs
@@ -1,6 +1,6 @@
īģŋusing System.Windows.Media;
using $safeprojectname$.Models;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.ViewModels.Pages
{
@@ -11,13 +11,15 @@ public partial class DataViewModel : ObservableObject, INavigationAware
[ObservableProperty]
private IEnumerable _colors;
- public void OnNavigatedTo()
+ public Task OnNavigatedToAsync()
{
if (!_isInitialized)
InitializeViewModel();
+
+ return Task.CompletedTask;
}
- public void OnNavigatedFrom() { }
+ public Task OnNavigatedFromAsync() => Task.CompletedTask;
private void InitializeViewModel()
{
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/ViewModels/Pages/SettingsViewModel.cs b/src/Wpf.Ui.Extension.Template.Fluent/ViewModels/Pages/SettingsViewModel.cs
index 2d0224df3..1a743f36e 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/ViewModels/Pages/SettingsViewModel.cs
+++ b/src/Wpf.Ui.Extension.Template.Fluent/ViewModels/Pages/SettingsViewModel.cs
@@ -1,5 +1,5 @@
īģŋusing Wpf.Ui.Appearance;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.ViewModels.Pages
{
@@ -13,13 +13,15 @@ public partial class SettingsViewModel : ObservableObject, INavigationAware
[ObservableProperty]
private ApplicationTheme _currentTheme = ApplicationTheme.Unknown;
- public void OnNavigatedTo()
+ public Task OnNavigatedToAsync()
{
if (!_isInitialized)
InitializeViewModel();
+
+ return Task.CompletedTask;
}
- public void OnNavigatedFrom() { }
+ public Task OnNavigatedFromAsync() => Task.CompletedTask;
private void InitializeViewModel()
{
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DashboardPage.xaml b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DashboardPage.xaml
index 0cf585792..91b9bd841 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DashboardPage.xaml
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DashboardPage.xaml
@@ -1,36 +1,37 @@
īģŋ
-
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DashboardPage.xaml.cs b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DashboardPage.xaml.cs
index 288b6feeb..97a97382d 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DashboardPage.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DashboardPage.xaml.cs
@@ -1,5 +1,5 @@
īģŋusing $safeprojectname$.ViewModels.Pages;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.Views.Pages
{
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DataPage.xaml b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DataPage.xaml
index 6268e0521..b745bb0f3 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DataPage.xaml
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DataPage.xaml
@@ -1,43 +1,45 @@
-
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ ScrollViewer.CanContentScroll="False"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DataPage.xaml.cs b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DataPage.xaml.cs
index 5c0fa3e89..566af09d4 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DataPage.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/DataPage.xaml.cs
@@ -1,5 +1,5 @@
īģŋusing $safeprojectname$.ViewModels.Pages;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.Views.Pages
{
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/SettingsPage.xaml b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/SettingsPage.xaml
index d0c1e49a8..06626db7e 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/SettingsPage.xaml
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/SettingsPage.xaml
@@ -1,51 +1,45 @@
īģŋ
-
-
-
-
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/SettingsPage.xaml.cs b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/SettingsPage.xaml.cs
index c3decb5af..ee4559d8f 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/SettingsPage.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Views/Pages/SettingsPage.xaml.cs
@@ -1,5 +1,5 @@
īģŋusing $safeprojectname$.ViewModels.Pages;
-using Wpf.Ui.Controls;
+using Wpf.Ui.Abstractions.Controls;
namespace $safeprojectname$.Views.Pages
{
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Views/Windows/MainWindow.xaml b/src/Wpf.Ui.Extension.Template.Fluent/Views/Windows/MainWindow.xaml
index 698cc8559..19590e6c6 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Views/Windows/MainWindow.xaml
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Views/Windows/MainWindow.xaml
@@ -1,65 +1,63 @@
īģŋ
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="450"
+ d:DesignWidth="800"
+ ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
+ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ ExtendsContentIntoTitleBar="True"
+ Foreground="{DynamicResource TextFillColorPrimaryBrush}"
+ WindowBackdropType="Mica"
+ WindowCornerPreference="Round"
+ WindowStartupLocation="CenterScreen"
+ mc:Ignorable="d"
+>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Views/Windows/MainWindow.xaml.cs b/src/Wpf.Ui.Extension.Template.Fluent/Views/Windows/MainWindow.xaml.cs
index 5e09543d8..8c138073b 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Views/Windows/MainWindow.xaml.cs
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Views/Windows/MainWindow.xaml.cs
@@ -1,5 +1,6 @@
īģŋusing $safeprojectname$.ViewModels.Windows;
using Wpf.Ui;
+using Wpf.Ui.Abstractions;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
@@ -11,7 +12,7 @@ public partial class MainWindow : INavigationWindow
public MainWindow(
MainWindowViewModel viewModel,
- IPageService pageService,
+ INavigationViewPageProvider navigationViewPageProvider,
INavigationService navigationService
)
{
@@ -21,7 +22,7 @@ INavigationService navigationService
SystemThemeWatcher.Watch(this);
InitializeComponent();
- SetPageService(pageService);
+ SetPageService(navigationViewPageProvider);
navigationService.SetNavigationControl(RootNavigation);
}
@@ -32,7 +33,7 @@ INavigationService navigationService
public bool Navigate(Type pageType) => RootNavigation.Navigate(pageType);
- public void SetPageService(IPageService pageService) => RootNavigation.SetPageService(pageService);
+ public void SetPageService(INavigationViewPageProvider navigationViewPageProvider) => RootNavigation.SetPageProviderService(navigationViewPageProvider);
public void ShowWindow() => Show();
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Extension.Template.Fluent.csproj b/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Extension.Template.Fluent.csproj
index 3962d3c05..e4ba5bf9b 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Extension.Template.Fluent.csproj
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Extension.Template.Fluent.csproj
@@ -1,7 +1,7 @@
īģŋ
-
+
+ true
17.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
@@ -10,6 +10,16 @@
15.0
+ win;win-x64;win-arm64
+ 8.0
+
+
+ true
+ bin\Debug\
+ DEBUG;TRACE
+ full
+ 11.0
+ prompt
true
@@ -20,6 +30,23 @@
11.0
prompt
+
+ true
+ bin\arm64\Debug\
+ DEBUG;TRACE
+ full
+ arm64
+ 11.0
+ prompt
+
+
+ bin\Release\
+ TRACE
+ true
+ pdbonly
+ 11.0
+ prompt
+
bin\x64\Release\
TRACE
@@ -29,17 +56,26 @@
11.0
prompt
+
+ bin\arm64\Release\
+ TRACE
+ true
+ pdbonly
+ arm64
+ 11.0
+ prompt
+
Debug
AnyCPU
{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {4d2706b5-27a9-4542-bd4d-8c22d12d0628}
+ {4D2706B5-27A9-4542-BD4D-8C22D12D0628}
Library
Properties
Wpf.Ui.Extension.Template.Fluent
Wpf.Ui.Extension.Template.Fluent
- v4.8
+ v4.8.1
false
false
false
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Fluent.csproj b/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Fluent.csproj
index d38989a09..9eb338561 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Fluent.csproj
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Fluent.csproj
@@ -2,7 +2,7 @@
WinExe
- net8.0-windows
+ net10.0-windows
app.manifest
wpfui-icon.ico
true
@@ -15,9 +15,10 @@
-
-
-
+
+
+
+
diff --git a/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Fluent.vstemplate b/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Fluent.vstemplate
index 6207098f9..ef4274f83 100644
--- a/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Fluent.vstemplate
+++ b/src/Wpf.Ui.Extension.Template.Fluent/Wpf.Ui.Fluent.vstemplate
@@ -39,7 +39,6 @@
ApplicationHostService.cs
- PageService.cs
diff --git a/src/Wpf.Ui.Extension/Properties/AssemblyInfo.cs b/src/Wpf.Ui.Extension/Properties/AssemblyInfo.cs
deleted file mode 100644
index 1f3e42bdd..000000000
--- a/src/Wpf.Ui.Extension/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-īģŋusing System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("WPF UI")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("WPF UI")]
-[assembly: AssemblyCopyright("")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj b/src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj
index 32b894779..757b57fb5 100644
--- a/src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj
+++ b/src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj
@@ -1,11 +1,23 @@
īģŋ
- 17.0
- win;win-x64
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+ true
+ 8.0
+ 17.0
+ win;win-x64;win-arm64
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 11.0
+ 4
+
true
bin\x64\Debug\
@@ -15,6 +27,23 @@
11.0
prompt
+
+ true
+ bin\arm64\Debug\
+ DEBUG;TRACE
+ full
+ ARM64
+ 11.0
+ prompt
+
+
+ pdbonly
+ false
+ bin\Release\
+ TRACE;DEBUG
+ prompt
+ 4
+
bin\x64\Release\
TRACE
@@ -24,6 +53,15 @@
11.0
prompt
+
+ bin\arm64\Release\
+ TRACE
+ true
+ pdbonly
+ ARM64
+ 11.0
+ prompt
+
Debug
@@ -35,7 +73,7 @@
Properties
Wpf.Ui.Extension
Wpf.Ui.Extension
- v4.8
+ v4.8.1
false
false
false
@@ -46,35 +84,11 @@
$(DevEnvDir)devenv.exe
/rootsuffix Exp
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
-
Designer
-
-
-
-
Always
@@ -114,4 +128,4 @@
-
\ No newline at end of file
+
diff --git a/src/Wpf.Ui.Extension/license.txt b/src/Wpf.Ui.Extension/license.txt
index 75e41fa10..540d1d913 100644
--- a/src/Wpf.Ui.Extension/license.txt
+++ b/src/Wpf.Ui.Extension/license.txt
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2021-2024 Leszek Pomianowski and WPF UI Contributors. https://dev.lepo.co/
+Copyright (c) 2021-2025 Leszek Pomianowski and WPF UI Contributors. https://lepo.co/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/src/Wpf.Ui.Extension/source.extension.vsixmanifest b/src/Wpf.Ui.Extension/source.extension.vsixmanifest
index 030d4e2d1..4df3e9f9c 100644
--- a/src/Wpf.Ui.Extension/source.extension.vsixmanifest
+++ b/src/Wpf.Ui.Extension/source.extension.vsixmanifest
@@ -1,7 +1,7 @@
-
+
WPF UI
WPF UI provides the Fluent experience in your known and loved WPF framework. Intuitive design, themes, navigation and new immersive controls. All natively and effortlessly.
https://github.com/lepoco/wpfui
@@ -13,9 +13,12 @@
wpf ui wpfui fluent design winui windows controls custom metro modern xaml toolkit color dark theme lepo net6 net5 net
-
@@ -27,7 +30,6 @@
-
diff --git a/src/Wpf.Ui.FlaUI/AutoSuggestBox.cs b/src/Wpf.Ui.FlaUI/AutoSuggestBox.cs
new file mode 100644
index 000000000..64f84b04a
--- /dev/null
+++ b/src/Wpf.Ui.FlaUI/AutoSuggestBox.cs
@@ -0,0 +1,41 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+namespace Wpf.Ui.FlaUI;
+
+///
+/// Class to interact with a WPF UI AutoSuggestBox element.
+///
+public class AutoSuggestBox(FrameworkAutomationElementBase frameworkAutomationElement)
+ : AutomationElement(frameworkAutomationElement)
+{
+ ///
+ /// Simulate typing in text.
+ ///
+ public void Enter(string value)
+ {
+ this.Click();
+
+ this.Patterns.Value.PatternOrDefault?.SetValue(string.Empty);
+ if (string.IsNullOrEmpty(value))
+ {
+ return;
+ }
+
+ string[] source = value.Replace("\r\n", "\n").Split('\n');
+
+ Keyboard.Type(source[0]);
+
+ foreach (string text in ((IEnumerable)source).Skip(1))
+ {
+ Keyboard.Type(VirtualKeyShort.RETURN);
+ Keyboard.Type(text);
+ }
+
+ Keyboard.Type(VirtualKeyShort.ENTER);
+
+ Wait.UntilInputIsProcessed();
+ }
+}
diff --git a/src/Wpf.Ui.FlaUI/GlobalUsings.cs b/src/Wpf.Ui.FlaUI/GlobalUsings.cs
new file mode 100644
index 000000000..ae05e5de4
--- /dev/null
+++ b/src/Wpf.Ui.FlaUI/GlobalUsings.cs
@@ -0,0 +1,13 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+global using System.Collections.Generic;
+global using System.Linq;
+global using FlaUI.Core;
+global using FlaUI.Core.AutomationElements;
+global using FlaUI.Core.Exceptions;
+global using FlaUI.Core.Input;
+global using FlaUI.Core.Patterns;
+global using FlaUI.Core.WindowsAPI;
diff --git a/src/Wpf.Ui.FlaUI/Wpf.Ui.FlaUI.csproj b/src/Wpf.Ui.FlaUI/Wpf.Ui.FlaUI.csproj
new file mode 100644
index 000000000..ccb9cc53a
--- /dev/null
+++ b/src/Wpf.Ui.FlaUI/Wpf.Ui.FlaUI.csproj
@@ -0,0 +1,22 @@
+īģŋ
+
+
+ WPF-UI.FlaUI
+ net10.0-windows;net9.0-windows;net8.0-windows;net481;
+ FlaUI automation library integration for WPF UI library.
+ $(CommonTags);syntax;highlight;flaui;fla;ui;ua3;ua2;ui;automation
+ true
+ true
+ true
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/src/Wpf.Ui.FontMapper/Wpf.Ui.FontMapper.csproj b/src/Wpf.Ui.FontMapper/Wpf.Ui.FontMapper.csproj
index c9595d6dc..906d93c6d 100644
--- a/src/Wpf.Ui.FontMapper/Wpf.Ui.FontMapper.csproj
+++ b/src/Wpf.Ui.FontMapper/Wpf.Ui.FontMapper.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net10.0
diff --git a/src/Wpf.Ui.Gallery.Package/Package.appxmanifest b/src/Wpf.Ui.Gallery.Package/Package.appxmanifest
index 44c1ef82b..a94001f4b 100644
--- a/src/Wpf.Ui.Gallery.Package/Package.appxmanifest
+++ b/src/Wpf.Ui.Gallery.Package/Package.appxmanifest
@@ -9,7 +9,7 @@
+ Version="4.0.0.0" />
WPF UI
diff --git a/src/Wpf.Ui.Gallery.Package/Wpf.Ui.Gallery.Package.wapproj b/src/Wpf.Ui.Gallery.Package/Wpf.Ui.Gallery.Package.wapproj
index aa72c787b..a17ba6af7 100644
--- a/src/Wpf.Ui.Gallery.Package/Wpf.Ui.Gallery.Package.wapproj
+++ b/src/Wpf.Ui.Gallery.Package/Wpf.Ui.Gallery.Package.wapproj
@@ -20,21 +20,13 @@
Release
x64
-
+
Debug
- ARM
+ arm64
-
+
Release
- ARM
-
-
- Debug
- ARM64
-
-
- Release
- ARM64
+ arm64
Debug
@@ -51,18 +43,37 @@
50c713c3-555e-491f-87ee-c806bec0579f
- 10.0.22621.0
- 10.0.14393.0
+ 10.0.26100.0
+ 10.0.18362.0
en-US
false
$(NoWarn);NU1701;NU1702
..\Wpf.Ui.Gallery\Wpf.Ui.Gallery.csproj
True
False
- True
+ False
True
- x86
+ x86|x64|arm64
0
+ SHA256
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
diff --git a/src/Wpf.Ui.Gallery/Controllers/MonacoController.cs b/src/Wpf.Ui.Gallery/Controllers/MonacoController.cs
index 9530789b0..b6a51231a 100644
--- a/src/Wpf.Ui.Gallery/Controllers/MonacoController.cs
+++ b/src/Wpf.Ui.Gallery/Controllers/MonacoController.cs
@@ -56,7 +56,7 @@ public async Task SetLanguageAsync(MonacoLanguage monacoLanguage)
var languageId =
monacoLanguage == MonacoLanguage.ObjectiveC ? "objective-c" : monacoLanguage.ToString().ToLower();
- await _webView.ExecuteScriptAsync(
+ _ = await _webView.ExecuteScriptAsync(
"monaco.editor.setModelLanguage(" + EditorObject + $".getModel(), \"{languageId}\");"
);
}
@@ -65,7 +65,7 @@ public async Task SetContentAsync(string contents)
{
var literalContents = SymbolDisplay.FormatLiteral(contents, false);
- await _webView.ExecuteScriptAsync(EditorObject + $".setValue(\"{literalContents}\");");
+ _ = await _webView.ExecuteScriptAsync(EditorObject + $".setValue(\"{literalContents}\");");
}
public void DispatchScript(string script)
@@ -75,6 +75,8 @@ public void DispatchScript(string script)
return;
}
- Application.Current.Dispatcher.InvokeAsync(async () => await _webView!.ExecuteScriptAsync(script));
+ _ = Application.Current.Dispatcher.InvokeAsync(async () =>
+ await _webView!.ExecuteScriptAsync(script)
+ );
}
}
diff --git a/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml b/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml
index a3f5a5c73..2600b11c4 100644
--- a/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml
+++ b/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml
@@ -14,11 +14,18 @@
+
+
+
+
+
+ TextWrapping="Wrap" />
+ TextWrapping="Wrap" />
-
-
-
-
-
diff --git a/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml.cs b/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml.cs
index f198369fd..1a3b401a9 100644
--- a/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml.cs
@@ -50,7 +50,7 @@ private void OnTemplateButtonClick(Type? pageType)
if (pageType is not null)
{
- navigationService.Navigate(pageType);
+ _ = navigationService.Navigate(pageType);
}
System.Diagnostics.Debug.WriteLine(
diff --git a/src/Wpf.Ui.Gallery/Controls/PageControlDocumentation.xaml.cs b/src/Wpf.Ui.Gallery/Controls/PageControlDocumentation.xaml.cs
index 6e0d1d9bd..630c027ea 100644
--- a/src/Wpf.Ui.Gallery/Controls/PageControlDocumentation.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Controls/PageControlDocumentation.xaml.cs
@@ -151,11 +151,12 @@ private void OnClick(string? param)
string navigationUrl = param switch
{
- "doc" when GetDocumentationType(_page) is { } documentationType
- => CreateUrlForDocumentation(documentationType),
+ "doc" when GetDocumentationType(_page) is { } documentationType => CreateUrlForDocumentation(
+ documentationType
+ ),
"xaml" => CreateUrlForGithub(_page.GetType(), ".xaml"),
"c#" => CreateUrlForGithub(_page.GetType(), ".xaml.cs"),
- _ => string.Empty
+ _ => string.Empty,
};
if (string.IsNullOrEmpty(navigationUrl))
diff --git a/src/Wpf.Ui.Gallery/Effects/Snowflake.cs b/src/Wpf.Ui.Gallery/Effects/Snowflake.cs
new file mode 100644
index 000000000..9ff53849a
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Effects/Snowflake.cs
@@ -0,0 +1,113 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Windows.Shapes;
+
+namespace Wpf.Ui.Gallery.Effects;
+
+///
+/// Snowflake data model
+///
+internal class SnowFlake
+{
+ private Ellipse? _shape;
+ private double _x;
+ private double _y;
+ private double _size;
+ private double _speed;
+ private double _opacity;
+ private double _velX;
+ private double _velY;
+ private double _stepSize;
+ private double _step;
+ private double _angle;
+ private TranslateTransform? _transform;
+
+ ///
+ /// Gets or sets shape of the snowflake
+ ///
+ public Ellipse? Shape
+ {
+ get => _shape;
+ set => _shape = value;
+ }
+
+ /// Gets or sets x position
+ public double X
+ {
+ get => _x;
+ set => _x = value;
+ }
+
+ /// Gets or sets Y position
+ public double Y
+ {
+ get => _y;
+ set => _y = value;
+ }
+
+ /// Gets or sets Size
+ public double Size
+ {
+ get => _size;
+ set => _size = value;
+ }
+
+ /// Gets or sets Falling speed
+ public double Speed
+ {
+ get => _speed;
+ set => _speed = value;
+ }
+
+ /// Gets or sets Opacity
+ public double Opacity
+ {
+ get => _opacity;
+ set => _opacity = value;
+ }
+
+ /// Gets or sets Horizontal velocity
+ public double VelX
+ {
+ get => _velX;
+ set => _velX = value;
+ }
+
+ /// Gets or sets Vertical velocity
+ public double VelY
+ {
+ get => _velY;
+ set => _velY = value;
+ }
+
+ /// Gets or sets Step size
+ public double StepSize
+ {
+ get => _stepSize;
+ set => _stepSize = value;
+ }
+
+ /// Gets or sets Step
+ public double Step
+ {
+ get => _step;
+ set => _step = value;
+ }
+
+ /// Gets or sets Angle
+ public double Angle
+ {
+ get => _angle;
+ set => _angle = value;
+ }
+
+ /// Gets or sets 2D coordinate transformation
+ public TranslateTransform? Transform
+ {
+ get => _transform;
+ set => _transform = value;
+ }
+}
diff --git a/src/Wpf.Ui.Gallery/Effects/SnowflakeEffect.cs b/src/Wpf.Ui.Gallery/Effects/SnowflakeEffect.cs
new file mode 100644
index 000000000..e60ae8045
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Effects/SnowflakeEffect.cs
@@ -0,0 +1,235 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Windows.Controls;
+using System.Windows.Shapes;
+
+namespace Wpf.Ui.Gallery.Effects;
+
+///
+/// Snow effect where the snowflakes are blown away by the mouse
+///
+internal class SnowflakeEffect
+{
+ private readonly Canvas _canvas; // Canvas for displaying snowflakes
+ private readonly Random _random = new(); // Random number generator
+ private readonly List _snowFlakes = []; // Stores all snowflake objects
+ private readonly int _flakeCount; // Number of snowflakes
+ private double mX = -100; // Mouse X-coordinate, default value -100
+ private double mY = -100; // Mouse Y-coordinate, default value -100
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The canvas where the effect is applied.
+ /// The number of snowflakes.
+ public SnowflakeEffect(Canvas canvas, int flakeCount = 188)
+ {
+ _canvas = canvas;
+ _flakeCount = flakeCount;
+ InitSnowFlakes();
+
+ if (_canvas.Parent is FrameworkElement parentElement)
+ {
+ parentElement.MouseMove += OnMouseMove;
+ parentElement.SizeChanged += OnSizeChanged;
+ }
+ }
+
+ ///
+ /// Starts displaying the snowflake effect
+ ///
+ public void Start()
+ {
+ CompositionTarget.Rendering += UpdateSnowFlakes;
+ }
+
+ ///
+ /// Stops displaying the snowflake effect and cleans up resources
+ ///
+ public void Stop()
+ {
+ CompositionTarget.Rendering -= UpdateSnowFlakes;
+ ClearSnowFlakes();
+
+ if (_canvas.Parent is FrameworkElement parentElement)
+ {
+ parentElement.MouseMove -= OnMouseMove;
+ parentElement.SizeChanged -= OnSizeChanged;
+ }
+
+ _canvas.Children.Clear();
+ }
+
+ ///
+ /// Initializes snowflake objects
+ ///
+ private void InitSnowFlakes()
+ {
+ for (int i = 0; i < _flakeCount; i++)
+ {
+ CreateSnowFlake();
+ }
+ }
+
+ ///
+ /// Creates a single snowflake and adds it to the canvas
+ ///
+ private void CreateSnowFlake()
+ {
+ double size = (_random.NextDouble() * 3) + 2; // Snowflake size
+ double speed = (_random.NextDouble() * 1) + 0.5; // Falling speed
+ double opacity = (_random.NextDouble() * 0.5) + 0.3; // Opacity
+ double x = _random.NextDouble() * _canvas.ActualWidth; // Initial X position
+ double y = _random.NextDouble() * _canvas.ActualHeight; // Initial Y position
+
+ Ellipse flakeShape = new()
+ {
+ Width = size,
+ Height = size,
+ Fill = new SolidColorBrush(Color.FromArgb((byte)(opacity * 255), 255, 255, 255)),
+ };
+
+ TranslateTransform transform = new(x, y);
+ flakeShape.RenderTransform = transform;
+
+ _ = _canvas.Children.Add(flakeShape);
+
+ SnowFlake flake = new()
+ {
+ Shape = flakeShape,
+ X = x,
+ Y = y,
+ Size = size,
+ Speed = speed,
+ Opacity = opacity,
+ VelX = 0,
+ VelY = speed,
+ StepSize = _random.NextDouble() / 30 * 1,
+ Step = 0,
+ Angle = 180,
+ Transform = transform,
+ };
+
+ _snowFlakes.Add(flake);
+ }
+
+ ///
+ /// Updates the position of snowflakes to respond to mouse movements
+ ///
+ private void UpdateSnowFlakes(object? sender, EventArgs e)
+ {
+ if (_canvas.ActualWidth == 0 || _canvas.ActualHeight == 0)
+ {
+ return;
+ }
+
+ foreach (SnowFlake flake in _snowFlakes)
+ {
+ double x = mX;
+ double y = mY;
+ double minDist = 150;
+ double x2 = flake.X;
+ double y2 = flake.Y;
+
+ double dist = Math.Sqrt(((x2 - x) * (x2 - x)) + ((y2 - y) * (y2 - y)));
+
+ if (dist < minDist)
+ {
+ double force = minDist / (dist * dist);
+ double xcomp = (x - x2) / dist;
+ double ycomp = (y - y2) / dist;
+ double deltaV = force / 2;
+
+ flake.VelX -= deltaV * xcomp;
+ flake.VelY -= deltaV * ycomp;
+ }
+ else
+ {
+ flake.VelX *= 0.98;
+ if (flake.VelY <= flake.Speed)
+ {
+ flake.VelY = flake.Speed;
+ }
+
+ flake.VelX += Math.Cos(flake.Step += 0.05) * flake.StepSize;
+ }
+
+ flake.Y += flake.VelY;
+ flake.X += flake.VelX;
+
+ if (flake.Y >= _canvas.ActualHeight || flake.Y <= 0)
+ {
+ ResetFlake(flake);
+ }
+
+ if (flake.X >= _canvas.ActualWidth || flake.X <= 0)
+ {
+ ResetFlake(flake);
+ }
+
+ flake.Transform!.SetCurrentValue(TranslateTransform.XProperty, flake.X);
+ flake.Transform!.SetCurrentValue(TranslateTransform.YProperty, flake.Y);
+ }
+ }
+
+ ///
+ /// Resets the position and properties of a snowflake when it moves out of view
+ ///
+ private void ResetFlake(SnowFlake flake)
+ {
+ flake.X = _random.NextDouble() * _canvas.ActualWidth;
+ flake.Y = 0;
+ flake.Size = (_random.NextDouble() * 3) + 2;
+ flake.Speed = (_random.NextDouble() * 1) + 0.5;
+ flake.VelY = flake.Speed;
+ flake.VelX = 0;
+ flake.Opacity = (_random.NextDouble() * 0.5) + 0.3;
+
+ if (flake.Shape == null)
+ {
+ return;
+ }
+
+ flake.Shape.SetCurrentValue(FrameworkElement.WidthProperty, flake.Size);
+ flake.Shape.SetCurrentValue(FrameworkElement.HeightProperty, flake.Size);
+ flake.Shape.SetCurrentValue(
+ Shape.FillProperty,
+ new SolidColorBrush(Color.FromArgb((byte)(flake.Opacity * 255), 255, 255, 255))
+ );
+ }
+
+ ///
+ /// Cleans up all snowflakes, used when stopping the effect
+ ///
+ private void ClearSnowFlakes()
+ {
+ foreach (SnowFlake flake in _snowFlakes)
+ {
+ _canvas.Children.Remove(flake.Shape);
+ }
+
+ _snowFlakes.Clear();
+ }
+
+ ///
+ /// Mouse move event handler, updates mouse position
+ ///
+ private void OnMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
+ {
+ Point position = e.GetPosition(_canvas);
+ mX = position.X;
+ mY = position.Y;
+ }
+
+ ///
+ /// Canvas size change event handler, updates canvas dimensions
+ ///
+ private void OnSizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ _canvas.SetCurrentValue(FrameworkElement.WidthProperty, e.NewSize.Width);
+ _canvas.SetCurrentValue(FrameworkElement.HeightProperty, e.NewSize.Height);
+ }
+}
diff --git a/src/Wpf.Ui.Gallery/Helpers/PaneDisplayModeToIndexConverter.cs b/src/Wpf.Ui.Gallery/Helpers/PaneDisplayModeToIndexConverter.cs
index 23bbf4a9e..6c638ed36 100644
--- a/src/Wpf.Ui.Gallery/Helpers/PaneDisplayModeToIndexConverter.cs
+++ b/src/Wpf.Ui.Gallery/Helpers/PaneDisplayModeToIndexConverter.cs
@@ -16,7 +16,7 @@ public object Convert(object? value, Type targetType, object? parameter, Culture
NavigationViewPaneDisplayMode.LeftFluent => 1,
NavigationViewPaneDisplayMode.Top => 2,
NavigationViewPaneDisplayMode.Bottom => 3,
- _ => 0
+ _ => 0,
};
}
@@ -27,7 +27,7 @@ public object ConvertBack(object? value, Type targetType, object? parameter, Cul
1 => NavigationViewPaneDisplayMode.LeftFluent,
2 => NavigationViewPaneDisplayMode.Top,
3 => NavigationViewPaneDisplayMode.Bottom,
- _ => NavigationViewPaneDisplayMode.Left
+ _ => NavigationViewPaneDisplayMode.Left,
};
}
}
diff --git a/src/Wpf.Ui.Gallery/Models/Product.cs b/src/Wpf.Ui.Gallery/Models/Product.cs
index 2f76bc433..b574c6a02 100644
--- a/src/Wpf.Ui.Gallery/Models/Product.cs
+++ b/src/Wpf.Ui.Gallery/Models/Product.cs
@@ -15,6 +15,8 @@ public class Product
public string? QuantityPerUnit { get; set; }
+ public Unit Unit { get; set; }
+
public double UnitPrice { get; set; }
public string UnitPriceString => UnitPrice.ToString("F2");
diff --git a/tests/Wpf.Ui.Gallery.UnitTests/Usings.cs b/src/Wpf.Ui.Gallery/Models/Unit.cs
similarity index 54%
rename from tests/Wpf.Ui.Gallery.UnitTests/Usings.cs
rename to src/Wpf.Ui.Gallery/Models/Unit.cs
index d5bf6204c..065a10000 100644
--- a/tests/Wpf.Ui.Gallery.UnitTests/Usings.cs
+++ b/src/Wpf.Ui.Gallery/Models/Unit.cs
@@ -1,6 +1,13 @@
-// This Source Code Form is subject to the terms of the MIT License.
+īģŋ// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
-global using Xunit;
+namespace Wpf.Ui.Gallery.Models;
+
+public enum Unit
+{
+ Grams,
+ Kilograms,
+ Milliliters,
+}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/AllControlsViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/AllControlsViewModel.cs
index 8aae53d39..0eea3970d 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/AllControlsViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/AllControlsViewModel.cs
@@ -19,7 +19,7 @@ public partial class AllControlsViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
.OrderBy(x => x.Name)
);
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/BasicInputViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/BasicInputViewModel.cs
index 01e60cf6d..c1a82aa73 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/BasicInputViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/BasicInputViewModel.cs
@@ -20,7 +20,7 @@ public partial class BasicInputViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/CheckBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/CheckBoxViewModel.cs
index ab53742e4..19704a0dd 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/CheckBoxViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/CheckBoxViewModel.cs
@@ -53,10 +53,9 @@ private void OnSingleChecked(string option)
bool allUnchecked =
!OptionOneCheckBoxChecked && !OptionTwoCheckBoxChecked && !OptionThreeCheckBoxChecked;
- SelectAllCheckBoxChecked = allChecked
- ? true
- : allUnchecked
- ? false
- : (bool?)null;
+ SelectAllCheckBoxChecked =
+ allChecked ? true
+ : allUnchecked ? false
+ : (bool?)null;
}
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ComboBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ComboBoxViewModel.cs
index d2a941272..9856fb18b 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ComboBoxViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ComboBoxViewModel.cs
@@ -13,7 +13,7 @@ public partial class ComboBoxViewModel : ViewModel
"Arial",
"Comic Sans MS",
"Segoe UI",
- "Times New Roman"
+ "Times New Roman",
];
[ObservableProperty]
@@ -32,6 +32,6 @@ public partial class ComboBoxViewModel : ViewModel
28,
36,
48,
- 72
+ 72,
];
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ThumbRateViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ThumbRateViewModel.cs
index 1253e33fd..2e35c0cf1 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ThumbRateViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ThumbRateViewModel.cs
@@ -26,7 +26,7 @@ public ThumbRateState ThumbRateState
{
ThumbRateState.Liked => "Liked",
ThumbRateState.Disliked => "Disliked",
- _ => "None"
+ _ => "None",
};
ThumRateStateCodeText = $"";
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/CollectionsViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/CollectionsViewModel.cs
index 823ff479b..fad839bdf 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/CollectionsViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/CollectionsViewModel.cs
@@ -20,7 +20,7 @@ public partial class CollectionsViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/DataGridViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/DataGridViewModel.cs
index cef593de8..9551d06a3 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/DataGridViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/DataGridViewModel.cs
@@ -19,7 +19,7 @@ private static ObservableCollection GenerateProducts()
var adjectives = new[] { "Red", "Blueberry" };
var names = new[] { "Marmalade", "Dumplings", "Soup" };
- /*var units = new[] { "grams", "kilograms", "milliliters" };*/
+ Unit[] units = [Unit.Grams, Unit.Kilograms, Unit.Milliliters];
for (int i = 0; i < 50; i++)
{
@@ -32,9 +32,10 @@ private static ObservableCollection GenerateProducts()
adjectives[random.Next(0, adjectives.Length)]
+ " "
+ names[random.Next(0, names.Length)],
+ Unit = units[random.Next(0, units.Length)],
UnitPrice = Math.Round(random.NextDouble() * 20.0, 3),
UnitsInStock = random.Next(0, 100),
- IsVirtual = random.Next(0, 2) == 1
+ IsVirtual = random.Next(0, 2) == 1,
}
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListBoxViewModel.cs
index 78ff39e9b..5114f48fd 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListBoxViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListBoxViewModel.cs
@@ -14,6 +14,6 @@ public partial class ListBoxViewModel : ViewModel
"Comic Sans MS",
"Courier New",
"Segoe UI",
- "Times New Roman"
+ "Times New Roman",
];
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListViewViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListViewViewModel.cs
index fb6a222e5..34ef73a3a 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListViewViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListViewViewModel.cs
@@ -48,7 +48,7 @@ private static ObservableCollection GeneratePersons()
"Arielle",
"Arielle",
"Jamie",
- "Alexzander"
+ "Alexzander",
};
var surnames = new[]
{
@@ -64,7 +64,7 @@ private static ObservableCollection GeneratePersons()
"Banks",
"Hood",
"Fry",
- "Carroll"
+ "Carroll",
};
var companies = new[]
{
@@ -74,7 +74,7 @@ private static ObservableCollection GeneratePersons()
"Megabyte Computers Inc",
"Roude Mics",
"XD Projekt Red S.A.",
- "Lepo.co"
+ "Lepo.co",
};
for (int i = 0; i < 50; i++)
@@ -97,7 +97,7 @@ private void UpdateListViewSelectionMode(int selectionModeIndex)
{
1 => SelectionMode.Multiple,
2 => SelectionMode.Extended,
- _ => SelectionMode.Single
+ _ => SelectionMode.Single,
};
}
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DateAndTime/DateAndTimeViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DateAndTime/DateAndTimeViewModel.cs
index 166dd1870..5d5d5ac77 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DateAndTime/DateAndTimeViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DateAndTime/DateAndTimeViewModel.cs
@@ -20,7 +20,7 @@ public partial class DateAndTimeViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DesignGuidance/IconsViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DesignGuidance/IconsViewModel.cs
index 51a3a97de..6bbf85181 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DesignGuidance/IconsViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DesignGuidance/IconsViewModel.cs
@@ -73,7 +73,7 @@ public IconsViewModel()
Name = iconName,
Icon = icon,
Symbol = ((char)icon).ToString(),
- Code = ((int)icon).ToString("X4")
+ Code = ((int)icon).ToString("X4"),
}
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/ContentDialogViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/ContentDialogViewModel.cs
index 66756260d..aa23b3fde 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/ContentDialogViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/ContentDialogViewModel.cs
@@ -32,7 +32,7 @@ private async Task OnShowDialog(object content)
{
ContentDialogResult.Primary => "User saved their work",
ContentDialogResult.Secondary => "User did not save their work",
- _ => "User cancelled the dialog"
+ _ => "User cancelled the dialog",
};
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/DialogsAndFlyoutsViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/DialogsAndFlyoutsViewModel.cs
index 892da7468..b9404a455 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/DialogsAndFlyoutsViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/DialogsAndFlyoutsViewModel.cs
@@ -20,7 +20,7 @@ public partial class DialogsAndFlyoutsViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/SnackbarViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/SnackbarViewModel.cs
index 7b8db4ece..7c6b386dc 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/SnackbarViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/SnackbarViewModel.cs
@@ -50,7 +50,7 @@ private void UpdateSnackbarAppearance(int appearanceIndex)
6 => ControlAppearance.Light,
7 => ControlAppearance.Dark,
8 => ControlAppearance.Transparent,
- _ => ControlAppearance.Primary
+ _ => ControlAppearance.Primary,
};
}
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Layout/LayoutViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Layout/LayoutViewModel.cs
index 975aff3be..4e1778e70 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Layout/LayoutViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Layout/LayoutViewModel.cs
@@ -20,7 +20,7 @@ public partial class LayoutViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Media/MediaViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Media/MediaViewModel.cs
index 527a880e7..4840a6537 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Media/MediaViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Media/MediaViewModel.cs
@@ -20,7 +20,7 @@ public partial class MediaViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/BreadcrumbBarViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/BreadcrumbBarViewModel.cs
index 9bf739c56..2ad7cf6d7 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/BreadcrumbBarViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/BreadcrumbBarViewModel.cs
@@ -27,7 +27,7 @@ public partial class BreadcrumbBarViewModel : ViewModel
"Images",
"Folder1",
"Folder2",
- "Folder3"
+ "Folder3",
];
[ObservableProperty]
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/NavigationViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/NavigationViewModel.cs
index cfb96f614..55a794ac0 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/NavigationViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/NavigationViewModel.cs
@@ -20,7 +20,7 @@ public partial class NavigationViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/FilePickerViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/FilePickerViewModel.cs
index 5414ae842..6c860e820 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/FilePickerViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/FilePickerViewModel.cs
@@ -50,12 +50,11 @@ public void OnOpenFile()
{
OpenedFilePathVisibility = Visibility.Collapsed;
- OpenFileDialog openFileDialog =
- new()
- {
- InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
- Filter = "All files (*.*)|*.*"
- };
+ OpenFileDialog openFileDialog = new()
+ {
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+ Filter = "All files (*.*)|*.*",
+ };
if (openFileDialog.ShowDialog() != true)
{
@@ -76,12 +75,11 @@ public void OnOpenPicture()
{
OpenedPicturePathVisibility = Visibility.Collapsed;
- OpenFileDialog openFileDialog =
- new()
- {
- InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
- Filter = "Image files (*.bmp;*.jpg;*.jpeg;*.png)|*.bmp;*.jpg;*.jpeg;*.png|All files (*.*)|*.*"
- };
+ OpenFileDialog openFileDialog = new()
+ {
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
+ Filter = "Image files (*.bmp;*.jpg;*.jpeg;*.png)|*.bmp;*.jpg;*.jpeg;*.png|All files (*.*)|*.*",
+ };
if (openFileDialog.ShowDialog() != true)
{
@@ -102,13 +100,12 @@ public void OnOpenMultiple()
{
OpenedMultiplePathVisibility = Visibility.Collapsed;
- OpenFileDialog openFileDialog =
- new()
- {
- Multiselect = true,
- InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
- Filter = "All files (*.*)|*.*"
- };
+ OpenFileDialog openFileDialog = new()
+ {
+ Multiselect = true,
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+ Filter = "All files (*.*)|*.*",
+ };
if (openFileDialog.ShowDialog() != true)
{
@@ -132,12 +129,11 @@ public void OnOpenFolder()
#if NET8_0_OR_GREATER
OpenedFolderPathVisibility = Visibility.Collapsed;
- OpenFolderDialog openFolderDialog =
- new()
- {
- Multiselect = true,
- InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
- };
+ OpenFolderDialog openFolderDialog = new()
+ {
+ Multiselect = true,
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+ };
if (openFolderDialog.ShowDialog() != true)
{
@@ -162,12 +158,11 @@ public async Task OnSaveFile(CancellationToken cancellation)
{
SavedFileNoticeVisibility = Visibility.Collapsed;
- SaveFileDialog saveFileDialog =
- new()
- {
- Filter = "Text Files (*.txt)|*.txt",
- InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
- };
+ SaveFileDialog saveFileDialog = new()
+ {
+ Filter = "Text Files (*.txt)|*.txt",
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+ };
if (!string.IsNullOrEmpty(FileToSaveName))
{
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/OpSystemViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/OpSystemViewModel.cs
index d52cd68fb..9c6ddc2cc 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/OpSystemViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/OpSystemViewModel.cs
@@ -20,7 +20,7 @@ public partial class OpSystemViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBadgeViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBadgeViewModel.cs
index 309f99cd0..fde1b1938 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBadgeViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBadgeViewModel.cs
@@ -32,7 +32,7 @@ private static InfoBadgeSeverity ConvertIndexToInfoBadgeSeverity(int value)
2 => InfoBadgeSeverity.Success,
3 => InfoBadgeSeverity.Caution,
4 => InfoBadgeSeverity.Critical,
- _ => InfoBadgeSeverity.Attention
+ _ => InfoBadgeSeverity.Attention,
};
}
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBarViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBarViewModel.cs
index 0ffae8af4..175312379 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBarViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBarViewModel.cs
@@ -54,7 +54,7 @@ private static InfoBarSeverity ConvertIndexToInfoBarSeverity(int value)
1 => InfoBarSeverity.Success,
2 => InfoBarSeverity.Warning,
3 => InfoBarSeverity.Error,
- _ => InfoBarSeverity.Informational
+ _ => InfoBarSeverity.Informational,
};
}
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/StatusAndInfoViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/StatusAndInfoViewModel.cs
index 1fafb8ddc..eb0acfd75 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/StatusAndInfoViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/StatusAndInfoViewModel.cs
@@ -20,7 +20,7 @@ public partial class StatusAndInfoViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/AutoSuggestBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/AutoSuggestBoxViewModel.cs
index 932cc4f20..18d571f15 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/AutoSuggestBoxViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/AutoSuggestBoxViewModel.cs
@@ -3,27 +3,42 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
+using System.Windows.Controls;
+
namespace Wpf.Ui.Gallery.ViewModels.Pages.Text;
public partial class AutoSuggestBoxViewModel : ViewModel
{
[ObservableProperty]
- private List _autoSuggestBoxSuggestions =
- new()
+ private List _autoSuggestBoxSuggestions = new()
+ {
+ "John",
+ "Winston",
+ "Adrianna",
+ "Spencer",
+ "Phoebe",
+ "Lucas",
+ "Carl",
+ "Marissa",
+ "Brandon",
+ "Antoine",
+ "Arielle",
+ "Arielle",
+ "Jamie",
+ "Alexzander",
+ };
+
+ [ObservableProperty]
+ private bool _showClearButton = true;
+
+ [RelayCommand]
+ private void OnShowClearButtonChecked(object sender)
+ {
+ if (sender is not CheckBox checkbox)
{
- "John",
- "Winston",
- "Adrianna",
- "Spencer",
- "Phoebe",
- "Lucas",
- "Carl",
- "Marissa",
- "Brandon",
- "Antoine",
- "Arielle",
- "Arielle",
- "Jamie",
- "Alexzander"
- };
+ return;
+ }
+
+ ShowClearButton = !(checkbox.IsChecked ?? false);
+ }
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/TextViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/TextViewModel.cs
index f2b533ae2..466875d2a 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/TextViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/TextViewModel.cs
@@ -20,7 +20,7 @@ public partial class TextViewModel : ViewModel
Name = x.Name,
Icon = x.Icon,
Description = x.Description,
- PageType = x.PageType
+ PageType = x.PageType,
})
);
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/ViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/ViewModel.cs
index dcb66a09f..d82d5a5e3 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/ViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/ViewModel.cs
@@ -8,11 +8,11 @@ namespace Wpf.Ui.Gallery.ViewModels;
public abstract partial class ViewModel : ObservableObject, INavigationAware
{
///
- public virtual async Task OnNavigatedToAsync()
+ public virtual Task OnNavigatedToAsync()
{
- using CancellationTokenSource cts = new();
+ OnNavigatedTo();
- await DispatchAsync(OnNavigatedTo, cts.Token);
+ return Task.CompletedTask;
}
///
@@ -22,11 +22,11 @@ public virtual async Task OnNavigatedToAsync()
public virtual void OnNavigatedTo() { }
///
- public virtual async Task OnNavigatedFromAsync()
+ public virtual Task OnNavigatedFromAsync()
{
- using CancellationTokenSource cts = new();
+ OnNavigatedFrom();
- await DispatchAsync(OnNavigatedFrom, cts.Token);
+ return Task.CompletedTask;
}
///
@@ -34,20 +34,4 @@ public virtual async Task OnNavigatedFromAsync()
///
// ReSharper disable once MemberCanBeProtected.Global
public virtual void OnNavigatedFrom() { }
-
- ///
- /// Dispatches the specified action on the UI thread.
- ///
- /// The action to be dispatched.
- /// A cancellation token that can be used to cancel the operation.
- /// A task that represents the asynchronous operation.
- protected static async Task DispatchAsync(Action action, CancellationToken cancellationToken)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- return;
- }
-
- await Application.Current.Dispatcher.InvokeAsync(action);
- }
}
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
index c6101117e..57bbb17d5 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
@@ -41,8 +41,8 @@ public partial class MainWindowViewModel(IStringLocalizer localize
{
new NavigationViewItem("Typography", SymbolRegular.TextFont24, typeof(TypographyPage)),
new NavigationViewItem("Icons", SymbolRegular.Diversity24, typeof(IconsPage)),
- new NavigationViewItem("Colors", SymbolRegular.Color24, typeof(ColorsPage))
- }
+ new NavigationViewItem("Colors", SymbolRegular.Color24, typeof(ColorsPage)),
+ },
},
new NavigationViewItem("All samples", SymbolRegular.List24, typeof(AllControlsPage)),
new NavigationViewItemSeparator(),
@@ -63,7 +63,7 @@ public partial class MainWindowViewModel(IStringLocalizer localize
new NavigationViewItem(nameof(ThumbRate), typeof(ThumbRatePage)),
new NavigationViewItem(nameof(SplitButton), typeof(SplitButtonPage)),
new NavigationViewItem(nameof(Slider), typeof(SliderPage)),
- }
+ },
},
new NavigationViewItem
{
@@ -79,7 +79,7 @@ public partial class MainWindowViewModel(IStringLocalizer localize
#if DEBUG
new NavigationViewItem("TreeList", typeof(TreeListPage)),
#endif
- }
+ },
},
new NavigationViewItem("Date & time", SymbolRegular.CalendarClock24, typeof(DateAndTimePage))
{
@@ -88,8 +88,8 @@ public partial class MainWindowViewModel(IStringLocalizer localize
new NavigationViewItem(nameof(CalendarDatePicker), typeof(CalendarDatePickerPage)),
new NavigationViewItem(nameof(System.Windows.Controls.Calendar), typeof(CalendarPage)),
new NavigationViewItem(nameof(DatePicker), typeof(DatePickerPage)),
- new NavigationViewItem(nameof(TimePicker), typeof(TimePickerPage))
- }
+ new NavigationViewItem(nameof(TimePicker), typeof(TimePickerPage)),
+ },
},
new NavigationViewItem("Dialogs & flyouts", SymbolRegular.Chat24, typeof(DialogsAndFlyoutsPage))
{
@@ -99,7 +99,7 @@ public partial class MainWindowViewModel(IStringLocalizer localize
new NavigationViewItem(nameof(ContentDialog), typeof(ContentDialogPage)),
new NavigationViewItem(nameof(Flyout), typeof(FlyoutPage)),
new NavigationViewItem(nameof(Wpf.Ui.Controls.MessageBox), typeof(MessageBoxPage)),
- }
+ },
},
#if DEBUG
new NavigationViewItem("Layout", SymbolRegular.News24, typeof(LayoutPage))
@@ -108,7 +108,7 @@ public partial class MainWindowViewModel(IStringLocalizer localize
{
new NavigationViewItem("Expander", typeof(ExpanderPage)),
new NavigationViewItem("CardControl", typeof(CardControlPage)),
- new NavigationViewItem("CardAction", typeof(CardActionPage))
+ new NavigationViewItem("CardAction", typeof(CardActionPage)),
},
},
#endif
@@ -122,8 +122,8 @@ public partial class MainWindowViewModel(IStringLocalizer localize
new NavigationViewItem("Image", typeof(ImagePage)),
new NavigationViewItem("Canvas", typeof(CanvasPage)),
new NavigationViewItem("WebView", typeof(WebViewPage)),
- new NavigationViewItem("WebBrowser", typeof(WebBrowserPage))
- }
+ new NavigationViewItem("WebBrowser", typeof(WebBrowserPage)),
+ },
},
new NavigationViewItem("Navigation", SymbolRegular.Navigation24, typeof(NavigationPage))
{
@@ -133,8 +133,8 @@ public partial class MainWindowViewModel(IStringLocalizer localize
new NavigationViewItem("NavigationView", typeof(NavigationViewPage)),
new NavigationViewItem("Menu", typeof(MenuPage)),
new NavigationViewItem("Multilevel navigation", typeof(MultilevelNavigationPage)),
- new NavigationViewItem("TabControl", typeof(TabControlPage))
- }
+ new NavigationViewItem("TabControl", typeof(TabControlPage)),
+ },
},
new NavigationViewItem(
"Status & info",
@@ -148,8 +148,8 @@ public partial class MainWindowViewModel(IStringLocalizer localize
new NavigationViewItem("InfoBar", typeof(InfoBarPage)),
new NavigationViewItem("ProgressBar", typeof(ProgressBarPage)),
new NavigationViewItem("ProgressRing", typeof(ProgressRingPage)),
- new NavigationViewItem("ToolTip", typeof(ToolTipPage))
- }
+ new NavigationViewItem("ToolTip", typeof(ToolTipPage)),
+ },
},
new NavigationViewItem("Text", SymbolRegular.DrawText24, typeof(TextPage))
{
@@ -162,7 +162,7 @@ public partial class MainWindowViewModel(IStringLocalizer localize
new NavigationViewItem(nameof(Label), typeof(LabelPage)),
new NavigationViewItem(nameof(Wpf.Ui.Controls.TextBlock), typeof(TextBlockPage)),
new NavigationViewItem(nameof(Wpf.Ui.Controls.TextBox), typeof(TextBoxPage)),
- }
+ },
},
new NavigationViewItem("System", SymbolRegular.Desktop24, typeof(OpSystemPage))
{
@@ -170,21 +170,38 @@ public partial class MainWindowViewModel(IStringLocalizer localize
{
new NavigationViewItem("Clipboard", typeof(ClipboardPage)),
new NavigationViewItem("FilePicker", typeof(FilePickerPage)),
- }
+ },
},
- new NavigationViewItem("Windows", SymbolRegular.WindowApps24, typeof(WindowsPage))
+ new NavigationViewItem("Windows", SymbolRegular.WindowApps24, typeof(WindowsPage)),
];
[ObservableProperty]
private ObservableCollection
-
- all
- build; analyzers
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
diff --git a/src/Wpf.Ui.Tray/Controls/NotifyIcon.cs b/src/Wpf.Ui.Tray/Controls/NotifyIcon.cs
index e99643035..57197c7c2 100644
--- a/src/Wpf.Ui.Tray/Controls/NotifyIcon.cs
+++ b/src/Wpf.Ui.Tray/Controls/NotifyIcon.cs
@@ -246,6 +246,9 @@ public NotifyIcon()
internalNotifyIconManager = new Wpf.Ui.Tray.Internal.InternalNotifyIconManager();
RegisterHandlers();
+
+ // Listen for DataContext changes to update ContextMenu
+ DataContextChanged += OnDataContextChanged;
}
///
@@ -363,6 +366,9 @@ protected virtual void Dispose(bool disposing)
System.Diagnostics.Debug.WriteLine($"INFO | {typeof(NotifyIcon)} disposed.", "Wpf.Ui.NotifyIcon");
+ // Clean up event handlers
+ DataContextChanged -= OnDataContextChanged;
+
Unregister();
internalNotifyIconManager.Dispose();
@@ -375,6 +381,13 @@ protected virtual void Dispose(bool disposing)
protected virtual void OnMenuChanged(ContextMenu contextMenu)
{
internalNotifyIconManager.ContextMenu = contextMenu;
+
+ // Set the DataContext for ContextMenu to enable binding
+ if (contextMenu.DataContext == null && DataContext != null)
+ {
+ contextMenu.DataContext = DataContext;
+ }
+
internalNotifyIconManager.ContextMenu.SetCurrentValue(Control.FontSizeProperty, MenuFontSize);
}
@@ -385,7 +398,6 @@ private static void OnTooltipTextChanged(DependencyObject d, DependencyPropertyC
return;
}
- notifyIcon.TooltipText = e.NewValue as string ?? string.Empty;
notifyIcon.internalNotifyIconManager.TooltipText = notifyIcon.TooltipText;
_ = notifyIcon.internalNotifyIconManager.ModifyToolTip();
}
@@ -411,7 +423,6 @@ private static void OnFocusOnLeftClickChanged(DependencyObject d, DependencyProp
if (e.NewValue is not bool newValue)
{
notifyIcon.FocusOnLeftClick = false;
-
return;
}
@@ -428,7 +439,6 @@ private static void OnMenuOnRightClickChanged(DependencyObject d, DependencyProp
if (e.NewValue is not bool newValue)
{
notifyIcon.MenuOnRightClick = false;
-
return;
}
@@ -456,6 +466,12 @@ private void InitializeIcon()
internalNotifyIconManager.Icon = Icon;
internalNotifyIconManager.MenuOnRightClick = MenuOnRightClick;
internalNotifyIconManager.FocusOnLeftClick = FocusOnLeftClick;
+
+ // Add Menu initialization
+ if (Menu != null)
+ {
+ OnMenuChanged(Menu);
+ }
}
private void RegisterHandlers()
@@ -467,4 +483,13 @@ private void RegisterHandlers()
internalNotifyIconManager.MiddleClick += OnMiddleClick;
internalNotifyIconManager.MiddleDoubleClick += OnMiddleDoubleClick;
}
+
+ private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
+ {
+ // Menu?.DataContext = e.NewValue;
+ if (Menu != null)
+ {
+ Menu.DataContext = e.NewValue;
+ }
+ }
}
diff --git a/src/Wpf.Ui.Tray/Hicon.cs b/src/Wpf.Ui.Tray/Hicon.cs
index 16ec08f89..b11516b94 100644
--- a/src/Wpf.Ui.Tray/Hicon.cs
+++ b/src/Wpf.Ui.Tray/Hicon.cs
@@ -5,7 +5,7 @@
// TODO: This class is the only reason for using System.Drawing.Common.
// It is worth looking for a way to get hIcon without using it.
-
+//
using System.Drawing;
using System.Windows.Media;
using System.Windows.Media.Imaging;
diff --git a/src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs b/src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs
index 213b4f9a6..9a2b059bb 100644
--- a/src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs
+++ b/src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs
@@ -177,8 +177,11 @@ protected virtual void OpenMenu()
}
// Without setting the handler window at the front, menu may appear behind the taskbar
- Interop.User32.SetForegroundWindow(HookWindow.Handle);
- ContextMenuService.SetPlacement(ContextMenu, PlacementMode.MousePoint);
+ _ = Interop.User32.SetForegroundWindow(HookWindow.Handle);
+
+ // Set placement properties for better positioning
+ ContextMenu.SetCurrentValue(ContextMenu.PlacementProperty, PlacementMode.MousePoint);
+ ContextMenu.SetCurrentValue(ContextMenu.PlacementTargetProperty, null);
// ContextMenu.ApplyMica();
ContextMenu.SetCurrentValue(ContextMenu.IsOpenProperty, true);
@@ -259,7 +262,7 @@ protected virtual void Dispose(bool disposing)
"Wpf.Ui.NotifyIcon"
);
- Unregister();
+ _ = Unregister();
}
///
diff --git a/src/Wpf.Ui.Tray/Interop/Shell32.cs b/src/Wpf.Ui.Tray/Interop/Shell32.cs
index 594e563e0..9ed503ebe 100644
--- a/src/Wpf.Ui.Tray/Interop/Shell32.cs
+++ b/src/Wpf.Ui.Tray/Interop/Shell32.cs
@@ -11,6 +11,7 @@ namespace Wpf.Ui.Tray.Interop;
// ReSharper disable InconsistentNaming
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
#pragma warning disable SA1401 // Fields should be private
+#pragma warning disable CA1060 // Move pinvokes to native methods class
///
/// The Windows UI provides users with access to a wide variety of objects necessary to run applications and manage the operating system.
@@ -178,3 +179,4 @@ public static extern int GetCurrentProcessExplicitAppUserModelID(
#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
#pragma warning restore SA1401 // Fields should be private
+#pragma warning restore CA1060 // Move pinvokes to native methods class
diff --git a/src/Wpf.Ui.Tray/Interop/User32.cs b/src/Wpf.Ui.Tray/Interop/User32.cs
index 1a1482e79..567438008 100644
--- a/src/Wpf.Ui.Tray/Interop/User32.cs
+++ b/src/Wpf.Ui.Tray/Interop/User32.cs
@@ -11,6 +11,7 @@ namespace Wpf.Ui.Tray.Interop;
// ReSharper disable InconsistentNaming
#pragma warning disable SA1300 // Element should begin with upper-case letter
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
+#pragma warning disable CA1060 // Move pinvokes to native methods class
///
/// USER procedure declarations, constant definitions and macros.
@@ -186,7 +187,7 @@ public enum WM_NCHITTEST
HTSIZELAST = HTBOTTOMRIGHT,
HTOBJECT = 19,
HTCLOSE = 20,
- HTHELP = 21
+ HTHELP = 21,
}
///
@@ -246,7 +247,7 @@ public enum GWL
///
/// Sets the new address of the dialog box procedure.
///
- DWLP_DLGPROC = 0x4
+ DWLP_DLGPROC = 0x4,
}
///
@@ -284,7 +285,7 @@ public enum WCA
WCA_CORNER_STYLE = 27,
WCA_PART_COLOR = 28,
WCA_DISABLE_MOVESIZE_FEEDBACK = 29,
- WCA_LAST = 30
+ WCA_LAST = 30,
}
[Flags]
@@ -294,7 +295,7 @@ public enum ACCENT_FLAGS
DrawTopBorder = 0x40,
DrawRightBorder = 0x80,
DrawBottomBorder = 0x100,
- DrawAllBorders = DrawLeftBorder | DrawTopBorder | DrawRightBorder | DrawBottomBorder
+ DrawAllBorders = DrawLeftBorder | DrawTopBorder | DrawRightBorder | DrawBottomBorder,
}
///
@@ -307,7 +308,7 @@ public enum ACCENT_STATE
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
- ACCENT_INVALID_STATE = 5
+ ACCENT_INVALID_STATE = 5,
}
///
@@ -348,7 +349,7 @@ public enum CS : uint
BYTEALIGNWINDOW = 0x2000,
GLOBALCLASS = 0x4000,
IME = 0x00010000,
- DROPSHADOW = 0x00020000
+ DROPSHADOW = 0x00020000,
}
///
@@ -1546,3 +1547,4 @@ public static extern int GetWindowCompositionAttribute(
#pragma warning restore SA1300 // Element should begin with upper-case letter
#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
+#pragma warning restore CA1060 // Move pinvokes to native methods class
diff --git a/src/Wpf.Ui.Tray/NotifyIconService.cs b/src/Wpf.Ui.Tray/NotifyIconService.cs
index 41b8a078e..40166d413 100644
--- a/src/Wpf.Ui.Tray/NotifyIconService.cs
+++ b/src/Wpf.Ui.Tray/NotifyIconService.cs
@@ -7,6 +7,8 @@
using System.Windows.Controls;
using System.Windows.Media;
+#pragma warning disable CA1001 // Types that own disposable fields should be disposable
+
namespace Wpf.Ui.Tray;
///
@@ -119,3 +121,5 @@ private void RegisterHandlers()
internalNotifyIconManager.MiddleDoubleClick += OnMiddleDoubleClick;
}
}
+
+#pragma warning restore CA1001 // Types that own disposable fields should be disposable
diff --git a/src/Wpf.Ui.Tray/TrayManager.cs b/src/Wpf.Ui.Tray/TrayManager.cs
index 2f1055429..67b4c12bc 100644
--- a/src/Wpf.Ui.Tray/TrayManager.cs
+++ b/src/Wpf.Ui.Tray/TrayManager.cs
@@ -79,7 +79,7 @@ public static bool Register(INotifyIcon notifyIcon, HwndSource? parentSource)
parentSource.Handle
)
{
- ElementId = notifyIcon.Id
+ ElementId = notifyIcon.Id,
};
notifyIcon.ShellIconData = new Interop.Shell32.NOTIFYICONDATA
@@ -88,7 +88,7 @@ public static bool Register(INotifyIcon notifyIcon, HwndSource? parentSource)
uFlags = Interop.Shell32.NIF.MESSAGE,
uCallbackMessage = (int)Interop.User32.WM.TRAYMOUSEMESSAGE,
hWnd = notifyIcon.HookWindow.Handle,
- dwState = 0x2
+ dwState = 0x2,
};
if (!string.IsNullOrEmpty(notifyIcon.TooltipText))
diff --git a/src/Wpf.Ui.Tray/VisualStudioToolsManifest.xml b/src/Wpf.Ui.Tray/VisualStudioToolsManifest.xml
index a2aeaa701..51f057956 100644
--- a/src/Wpf.Ui.Tray/VisualStudioToolsManifest.xml
+++ b/src/Wpf.Ui.Tray/VisualStudioToolsManifest.xml
@@ -4,4 +4,4 @@
-
\ No newline at end of file
+
diff --git a/src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj b/src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj
index d672b22f0..a33fde3a9 100644
--- a/src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj
+++ b/src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj
@@ -2,11 +2,12 @@
WPF-UI.Tray
- net462;net472;net481;net6.0-windows;net8.0-windows
- true
+ net10.0-windows;net9.0-windows;net8.0-windows;net481;net472;net462
Native tray menu icon support for WPF using the WPF UI library.
$(CommonTags);tray;notifyicon;notify
true
+ true
+ true
@@ -34,18 +35,10 @@
-
- all
- build; analyzers
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
diff --git a/src/Wpf.Ui/Animations/AnimationProperties.cs b/src/Wpf.Ui/Animations/AnimationProperties.cs
new file mode 100644
index 000000000..5d2bb6cae
--- /dev/null
+++ b/src/Wpf.Ui/Animations/AnimationProperties.cs
@@ -0,0 +1,26 @@
+īģŋ// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+namespace Wpf.Ui.Animations;
+
+internal static class AnimationProperties
+{
+ public static readonly DependencyProperty AnimationTagValueProperty = DependencyProperty.RegisterAttached(
+ "AnimationTagValue",
+ typeof(double),
+ typeof(AnimationProperties),
+ new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.Inherits)
+ );
+
+ public static double GetAnimationTagValue(DependencyObject dp)
+ {
+ return (double)dp.GetValue(AnimationTagValueProperty);
+ }
+
+ public static void SetAnimationTagValue(DependencyObject dp, double value)
+ {
+ dp.SetValue(AnimationTagValueProperty, value);
+ }
+}
diff --git a/src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs b/src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs
index e0fac34f3..3b048e37c 100644
--- a/src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs
+++ b/src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs
@@ -3,8 +3,11 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
-using Wpf.Ui.Extensions;
+using System.IO;
+using System.Runtime.InteropServices;
using Wpf.Ui.Interop;
+using Wpf.Ui.Win32;
+using static Wpf.Ui.Appearance.UISettingsRCW;
namespace Wpf.Ui.Appearance;
@@ -29,6 +32,23 @@ namespace Wpf.Ui.Appearance;
///
public static class ApplicationAccentColorManager
{
+ private static readonly IUISettings3? _uisettings;
+ private static readonly bool _isSupported;
+
+ static ApplicationAccentColorManager()
+ {
+ try
+ {
+ _uisettings = GetWinRTInstance() as IUISettings3;
+ _isSupported = _uisettings != null;
+ }
+ catch (COMException)
+ {
+ // We don't want to throw any exceptions here.
+ // If we can't get the instance, we will use the fallback accent color.
+ }
+ }
+
///
/// The maximum value of the background HSV brightness after which the text on the accent will be turned dark.
///
@@ -126,6 +146,12 @@ public static Color TertiaryAccent
///
public static Brush TertiaryAccentBrush => new SolidColorBrush(TertiaryAccent);
+ ///
+ /// Gets a value indicating whether the user has enabled accent color on title bars and window borders in Windows settings.
+ ///
+ public static bool IsAccentColorOnTitleBarsEnabled =>
+ UnsafeNativeMethods.IsAccentColorOnTitleBarsEnabled();
+
///
/// Changes the color accents of the application based on the color entered.
///
@@ -144,24 +170,35 @@ public static void Apply(
systemAccent = systemAccent.UpdateBrightness(6f);
}
+ bool isSystemAccent = systemAccent == GetColorizationColor();
Color primaryAccent;
Color secondaryAccent;
Color tertiaryAccent;
if (applicationTheme == ApplicationTheme.Dark)
{
- primaryAccent = systemAccent.Update(15f, -12f);
- secondaryAccent = systemAccent.Update(30f, -24f);
- tertiaryAccent = systemAccent.Update(45f, -36f);
+ primaryAccent = GetColor(UIColorType.AccentLight1, 17, -30f);
+ secondaryAccent = GetColor(UIColorType.AccentLight2, 17, -45f);
+ tertiaryAccent = GetColor(UIColorType.AccentLight3, 17, -65f);
}
else
{
- primaryAccent = systemAccent.UpdateBrightness(-5f);
- secondaryAccent = systemAccent.UpdateBrightness(-10f);
- tertiaryAccent = systemAccent.UpdateBrightness(-15f);
+ primaryAccent = GetColor(UIColorType.AccentDark1, -10);
+ secondaryAccent = GetColor(UIColorType.AccentDark2, -25);
+ tertiaryAccent = GetColor(UIColorType.AccentDark3, -40);
}
- UpdateColorResources(systemAccent, primaryAccent, secondaryAccent, tertiaryAccent);
+ UpdateColorResources(applicationTheme, systemAccent, primaryAccent, secondaryAccent, tertiaryAccent);
+
+ Color GetColor(UIColorType colorType, float brightnessFactor, float saturationFactor = 0.0f)
+ {
+ if (isSystemAccent && GetUiColor(colorType) is { } color)
+ {
+ return color;
+ }
+
+ return systemAccent.Update(brightnessFactor, saturationFactor);
+ }
}
///
@@ -178,7 +215,13 @@ public static void Apply(
Color tertiaryAccent
)
{
- UpdateColorResources(systemAccent, primaryAccent, secondaryAccent, tertiaryAccent);
+ UpdateColorResources(
+ ApplicationThemeManager.GetAppTheme(),
+ systemAccent,
+ primaryAccent,
+ secondaryAccent,
+ tertiaryAccent
+ );
}
///
@@ -195,13 +238,19 @@ public static void ApplySystemAccent()
///
public static Color GetColorizationColor()
{
- return UnsafeNativeMethods.GetDwmColor();
+ if (GetUiColor(UIColorType.Accent) is { } accentColor)
+ {
+ return accentColor;
+ }
+
+ return UnsafeNativeMethods.GetAccentColor();
}
///
/// Updates application resources.
///
private static void UpdateColorResources(
+ ApplicationTheme applicationTheme,
Color systemAccent,
Color primaryAccent,
Color secondaryAccent,
@@ -296,16 +345,79 @@ Color tertiaryAccent
UiApplication.Current.Resources["SystemAccentColorSecondary"] = secondaryAccent;
UiApplication.Current.Resources["SystemAccentColorTertiary"] = tertiaryAccent;
- UiApplication.Current.Resources["SystemAccentBrush"] = secondaryAccent.ToBrush();
+ UiApplication.Current.Resources["SystemAccentBrush"] = systemAccent.ToBrush();
UiApplication.Current.Resources["SystemFillColorAttentionBrush"] = secondaryAccent.ToBrush();
- UiApplication.Current.Resources["AccentTextFillColorPrimaryBrush"] = tertiaryAccent.ToBrush();
+
+ UiApplication.Current.Resources["AccentTextFillColorPrimaryBrush"] = secondaryAccent.ToBrush();
UiApplication.Current.Resources["AccentTextFillColorSecondaryBrush"] = tertiaryAccent.ToBrush();
- UiApplication.Current.Resources["AccentTextFillColorTertiaryBrush"] = secondaryAccent.ToBrush();
+ UiApplication.Current.Resources["AccentTextFillColorTertiaryBrush"] = primaryAccent.ToBrush();
+
UiApplication.Current.Resources["AccentFillColorSelectedTextBackgroundBrush"] =
systemAccent.ToBrush();
- UiApplication.Current.Resources["AccentFillColorDefaultBrush"] = secondaryAccent.ToBrush();
- UiApplication.Current.Resources["AccentFillColorSecondaryBrush"] = secondaryAccent.ToBrush(0.9);
- UiApplication.Current.Resources["AccentFillColorTertiaryBrush"] = secondaryAccent.ToBrush(0.8);
+ var themeAccent = applicationTheme == ApplicationTheme.Dark ? secondaryAccent : primaryAccent;
+ UiApplication.Current.Resources["AccentFillColorDefault"] = themeAccent;
+ UiApplication.Current.Resources["AccentFillColorDefaultBrush"] = themeAccent.ToBrush();
+ UiApplication.Current.Resources["AccentFillColorSecondary"] = Color.FromArgb(
+ 229,
+ themeAccent.R,
+ themeAccent.G,
+ themeAccent.B
+ ); // 229 = 0.9 * 255
+ UiApplication.Current.Resources["AccentFillColorSecondaryBrush"] = themeAccent.ToBrush(0.9);
+ UiApplication.Current.Resources["AccentFillColorTertiary"] = Color.FromArgb(
+ 204,
+ themeAccent.R,
+ themeAccent.G,
+ themeAccent.B
+ ); // 204 = 0.8 * 255
+ UiApplication.Current.Resources["AccentFillColorTertiaryBrush"] = themeAccent.ToBrush(0.8);
+ }
+
+ ///
+ /// Gets the color of the UI.
+ ///
+ /// Type of the color.
+ private static Color? GetUiColor(UIColorType colorType)
+ {
+ if (_isSupported)
+ {
+ try
+ {
+ UIColor uiColor = _uisettings!.GetColorValue(colorType);
+ return Color.FromArgb(uiColor.A, uiColor.R, uiColor.G, uiColor.B);
+ }
+ catch
+ {
+ // We don't want to throw any exceptions here.
+ // If we can't get the instance, we can fallback to another method.
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Gets the WinRT instance of UISettings.
+ ///
+ private static object? GetWinRTInstance()
+ {
+ if (!Utilities.IsOSWindows10OrNewer)
+ {
+ return null;
+ }
+
+ object? winRtInstance;
+
+ try
+ {
+ winRtInstance = GetUISettingsInstance();
+ }
+ catch (Exception e) when (e is TypeLoadException or FileNotFoundException)
+ {
+ winRtInstance = null;
+ }
+
+ return winRtInstance;
}
}
diff --git a/src/Wpf.Ui/Appearance/ApplicationTheme.cs b/src/Wpf.Ui/Appearance/ApplicationTheme.cs
index 192e26a61..318a17c06 100644
--- a/src/Wpf.Ui/Appearance/ApplicationTheme.cs
+++ b/src/Wpf.Ui/Appearance/ApplicationTheme.cs
@@ -28,5 +28,5 @@ public enum ApplicationTheme
///
/// High contract application theme.
///
- HighContrast
+ HighContrast,
}
diff --git a/src/Wpf.Ui/Appearance/ApplicationThemeManager.cs b/src/Wpf.Ui/Appearance/ApplicationThemeManager.cs
index df7f69435..f6161fc9f 100644
--- a/src/Wpf.Ui/Appearance/ApplicationThemeManager.cs
+++ b/src/Wpf.Ui/Appearance/ApplicationThemeManager.cs
@@ -142,7 +142,7 @@ public static void Apply(FrameworkElement frameworkElement)
ResourceDictionary[] resourcesRemove = frameworkElement
.Resources.MergedDictionaries.Where(e => e.Source is not null)
- .Where(e => e.Source.ToString().ToLower().Contains(LibraryNamespace))
+ .Where(e => e.Source.ToString().Contains(LibraryNamespace, StringComparison.OrdinalIgnoreCase))
.ToArray();
foreach (ResourceDictionary? resource in UiApplication.Current.Resources.MergedDictionaries)
@@ -235,11 +235,15 @@ public static bool IsAppMatchesSystem()
return appApplicationTheme switch
{
- ApplicationTheme.Dark
- => sysTheme is SystemTheme.Dark or SystemTheme.CapturedMotion or SystemTheme.Glow,
- ApplicationTheme.Light
- => sysTheme is SystemTheme.Light or SystemTheme.Flow or SystemTheme.Sunrise,
- _ => appApplicationTheme == ApplicationTheme.HighContrast && SystemThemeManager.HighContrast
+ ApplicationTheme.Dark => sysTheme
+ is SystemTheme.Dark
+ or SystemTheme.CapturedMotion
+ or SystemTheme.Glow,
+ ApplicationTheme.Light => sysTheme
+ is SystemTheme.Light
+ or SystemTheme.Flow
+ or SystemTheme.Sunrise,
+ _ => appApplicationTheme == ApplicationTheme.HighContrast && SystemThemeManager.HighContrast,
};
}
@@ -288,19 +292,19 @@ private static void FetchApplicationTheme()
return;
}
- string themeUri = themeDictionary.Source.ToString().Trim().ToLower();
+ string themeUri = themeDictionary.Source.ToString();
- if (themeUri.Contains("light"))
+ if (themeUri.Contains("light", StringComparison.OrdinalIgnoreCase))
{
_cachedApplicationTheme = ApplicationTheme.Light;
}
- if (themeUri.Contains("dark"))
+ if (themeUri.Contains("dark", StringComparison.OrdinalIgnoreCase))
{
_cachedApplicationTheme = ApplicationTheme.Dark;
}
- if (themeUri.Contains("highcontrast"))
+ if (themeUri.Contains("highcontrast", StringComparison.OrdinalIgnoreCase))
{
_cachedApplicationTheme = ApplicationTheme.HighContrast;
}
diff --git a/src/Wpf.Ui/Appearance/ObservedWindow.cs b/src/Wpf.Ui/Appearance/ObservedWindow.cs
index 44e4c586c..dc0279896 100644
--- a/src/Wpf.Ui/Appearance/ObservedWindow.cs
+++ b/src/Wpf.Ui/Appearance/ObservedWindow.cs
@@ -15,7 +15,7 @@ internal class ObservedWindow
private readonly HwndSource _source;
///
- /// Initializes a new instance of the ObservedWindow class.
+ /// Initializes a new instance of the class.
///
/// The handle of the window.
/// The backdrop type of the window.
diff --git a/src/Wpf.Ui/Appearance/ResourceDictionaryManager.cs b/src/Wpf.Ui/Appearance/ResourceDictionaryManager.cs
index 01f0afc29..269230684 100644
--- a/src/Wpf.Ui/Appearance/ResourceDictionaryManager.cs
+++ b/src/Wpf.Ui/Appearance/ResourceDictionaryManager.cs
@@ -46,19 +46,17 @@ public bool HasDictionary(string resourceLookup)
return null;
}
- resourceLookup = resourceLookup.ToLower().Trim();
-
foreach (ResourceDictionary t in applicationDictionaries)
{
string resourceDictionaryUri;
if (t?.Source != null)
{
- resourceDictionaryUri = t.Source.ToString().ToLower().Trim();
+ resourceDictionaryUri = t.Source.ToString();
if (
- resourceDictionaryUri.Contains(SearchNamespace)
- && resourceDictionaryUri.Contains(resourceLookup)
+ resourceDictionaryUri.Contains(SearchNamespace, StringComparison.OrdinalIgnoreCase)
+ && resourceDictionaryUri.Contains(resourceLookup, StringComparison.OrdinalIgnoreCase)
)
{
return t;
@@ -72,11 +70,11 @@ public bool HasDictionary(string resourceLookup)
continue;
}
- resourceDictionaryUri = t1.Source.ToString().ToLower().Trim();
+ resourceDictionaryUri = t1.Source.ToString();
if (
- !resourceDictionaryUri.Contains(SearchNamespace)
- || !resourceDictionaryUri.Contains(resourceLookup)
+ !resourceDictionaryUri.Contains(SearchNamespace, StringComparison.OrdinalIgnoreCase)
+ || !resourceDictionaryUri.Contains(resourceLookup, StringComparison.OrdinalIgnoreCase)
)
{
continue;
@@ -107,17 +105,18 @@ public bool UpdateDictionary(string resourceLookup, Uri? newResourceUri)
return false;
}
- resourceLookup = resourceLookup.ToLower().Trim();
-
for (var i = 0; i < applicationDictionaries.Count; i++)
{
string sourceUri;
if (applicationDictionaries[i]?.Source != null)
{
- sourceUri = applicationDictionaries[i].Source.ToString().ToLower().Trim();
+ sourceUri = applicationDictionaries[i].Source.ToString();
- if (sourceUri.Contains(SearchNamespace) && sourceUri.Contains(resourceLookup))
+ if (
+ sourceUri.Contains(SearchNamespace, StringComparison.OrdinalIgnoreCase)
+ && sourceUri.Contains(resourceLookup, StringComparison.OrdinalIgnoreCase)
+ )
{
applicationDictionaries[i] = new() { Source = newResourceUri };
@@ -132,13 +131,12 @@ public bool UpdateDictionary(string resourceLookup, Uri? newResourceUri)
continue;
}
- sourceUri = applicationDictionaries[i]
- .MergedDictionaries[j]
- .Source.ToString()
- .ToLower()
- .Trim();
+ sourceUri = applicationDictionaries[i].MergedDictionaries[j].Source.ToString();
- if (!sourceUri.Contains(SearchNamespace) || !sourceUri.Contains(resourceLookup))
+ if (
+ !sourceUri.Contains(SearchNamespace, StringComparison.OrdinalIgnoreCase)
+ || !sourceUri.Contains(resourceLookup, StringComparison.OrdinalIgnoreCase)
+ )
{
continue;
}
diff --git a/src/Wpf.Ui/Appearance/SystemTheme.cs b/src/Wpf.Ui/Appearance/SystemTheme.cs
index 23cee95c1..238e5472e 100644
--- a/src/Wpf.Ui/Appearance/SystemTheme.cs
+++ b/src/Wpf.Ui/Appearance/SystemTheme.cs
@@ -68,5 +68,5 @@ public enum SystemTheme
///
/// Light theme: Flow
///
- Flow
+ Flow,
}
diff --git a/src/Wpf.Ui/Appearance/SystemThemeManager.cs b/src/Wpf.Ui/Appearance/SystemThemeManager.cs
index f14f33f33..57945aa7d 100644
--- a/src/Wpf.Ui/Appearance/SystemThemeManager.cs
+++ b/src/Wpf.Ui/Appearance/SystemThemeManager.cs
@@ -69,60 +69,58 @@ private static SystemTheme GetCurrentSystemTheme()
if (!string.IsNullOrEmpty(currentTheme))
{
- currentTheme = currentTheme.ToLower().Trim();
-
// This may be changed in the next versions, check the Insider previews
- if (currentTheme.Contains("basic.theme"))
+ if (currentTheme.Contains("basic.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.Light;
}
- if (currentTheme.Contains("aero.theme"))
+ if (currentTheme.Contains("aero.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.Light;
}
- if (currentTheme.Contains("dark.theme"))
+ if (currentTheme.Contains("dark.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.Dark;
}
- if (currentTheme.Contains("hcblack.theme"))
+ if (currentTheme.Contains("hcblack.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.HCBlack;
}
- if (currentTheme.Contains("hcwhite.theme"))
+ if (currentTheme.Contains("hcwhite.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.HCWhite;
}
- if (currentTheme.Contains("hc1.theme"))
+ if (currentTheme.Contains("hc1.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.HC1;
}
- if (currentTheme.Contains("hc2.theme"))
+ if (currentTheme.Contains("hc2.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.HC2;
}
- if (currentTheme.Contains("themea.theme"))
+ if (currentTheme.Contains("themea.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.Glow;
}
- if (currentTheme.Contains("themeb.theme"))
+ if (currentTheme.Contains("themeb.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.CapturedMotion;
}
- if (currentTheme.Contains("themec.theme"))
+ if (currentTheme.Contains("themec.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.Sunrise;
}
- if (currentTheme.Contains("themed.theme"))
+ if (currentTheme.Contains("themed.theme", StringComparison.OrdinalIgnoreCase))
{
return SystemTheme.Flow;
}
diff --git a/src/Wpf.Ui/Appearance/SystemThemeWatcher.cs b/src/Wpf.Ui/Appearance/SystemThemeWatcher.cs
index 7d300fe68..841a6b4bd 100644
--- a/src/Wpf.Ui/Appearance/SystemThemeWatcher.cs
+++ b/src/Wpf.Ui/Appearance/SystemThemeWatcher.cs
@@ -3,6 +3,7 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
+using Windows.Win32;
using Wpf.Ui.Controls;
using Wpf.Ui.Interop;
@@ -150,7 +151,7 @@ public static void UnWatch(Window? window)
///
private static IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
- if (msg == (int)User32.WM.WININICHANGE)
+ if (msg == (int)PInvoke.WM_WININICHANGE)
{
UpdateObservedWindow(hWnd);
}
diff --git a/src/Wpf.Ui/Appearance/UISettingsRCW.cs b/src/Wpf.Ui/Appearance/UISettingsRCW.cs
new file mode 100644
index 000000000..1a85d9a58
--- /dev/null
+++ b/src/Wpf.Ui/Appearance/UISettingsRCW.cs
@@ -0,0 +1,93 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Runtime.InteropServices;
+
+namespace Wpf.Ui.Appearance;
+
+///
+/// Contains internal RCWs for invoking the UISettings
+///
+internal static class UISettingsRCW
+{
+ public enum UIColorType
+ {
+ Background = 0,
+ Foreground = 1,
+ AccentDark3 = 2,
+ AccentDark2 = 3,
+ AccentDark1 = 4,
+ Accent = 5,
+ AccentLight1 = 6,
+ AccentLight2 = 7,
+ AccentLight3 = 8,
+ Complement = 9,
+ }
+
+ public static object GetUISettingsInstance()
+ {
+ const string typeName = "Windows.UI.ViewManagement.UISettings";
+
+ int hr = NativeMethods.WindowsCreateString(typeName, typeName.Length, out IntPtr hstring);
+ Marshal.ThrowExceptionForHR(hr);
+
+ try
+ {
+ hr = NativeMethods.RoActivateInstance(hstring, out object instance);
+ Marshal.ThrowExceptionForHR(hr);
+ return instance;
+ }
+ finally
+ {
+ hr = NativeMethods.WindowsDeleteString(hstring);
+ Marshal.ThrowExceptionForHR(hr);
+ }
+ }
+
+ ///
+ /// Contains internal RCWs for invoking the InputPane (tiptsf touch keyboard)
+ ///
+ internal static class NativeMethods
+ {
+ [DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
+ internal static extern int WindowsCreateString(
+ [MarshalAs(UnmanagedType.LPWStr)] string sourceString,
+ int length,
+ out IntPtr hstring
+ );
+
+ [DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
+ internal static extern int WindowsDeleteString(IntPtr hstring);
+
+ [DllImport("api-ms-win-core-winrt-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
+ internal static extern int RoActivateInstance(
+ IntPtr runtimeClassId,
+ [MarshalAs(UnmanagedType.Interface)] out object instance
+ );
+ }
+
+ [Guid("03021BE4-5254-4781-8194-5168F7D06D7B")]
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ internal interface IUISettings3
+ {
+ void GetIids(out uint iidCount, out IntPtr iids);
+
+ void GetRuntimeClassName(out string className);
+
+ void GetTrustLevel(out TrustLevel TrustLevel);
+
+ UIColor GetColorValue(UIColorType desiredColor);
+ }
+
+ internal enum TrustLevel
+ {
+ BaseTrust,
+ PartialTrust,
+ FullTrust,
+ }
+
+ internal readonly record struct UIColor(byte A, byte R, byte G, byte B);
+}
diff --git a/src/Wpf.Ui/Controls/Anchor/Anchor.cs b/src/Wpf.Ui/Controls/Anchor/Anchor.cs
index bc3bdedbe..207476f8a 100644
--- a/src/Wpf.Ui/Controls/Anchor/Anchor.cs
+++ b/src/Wpf.Ui/Controls/Anchor/Anchor.cs
@@ -14,7 +14,7 @@ namespace Wpf.Ui.Controls;
///
///
/// <ui:Anchor
-/// NavigateUri="https://dev.lepo.co/" />
+/// NavigateUri="https://lepo.co/" />
///
///
public class Anchor : Wpf.Ui.Controls.HyperlinkButton { }
diff --git a/src/Wpf.Ui/Controls/Arc/Arc.cs b/src/Wpf.Ui/Controls/Arc/Arc.cs
index c668584a7..104567443 100644
--- a/src/Wpf.Ui/Controls/Arc/Arc.cs
+++ b/src/Wpf.Ui/Controls/Arc/Arc.cs
@@ -52,13 +52,14 @@ public class Arc : Shape
new PropertyMetadata(SweepDirection.Clockwise, PropertyChangedCallback)
);
- /// Identifies the dependency property.
- public static readonly DependencyProperty StrokeStartLineCapProperty = DependencyProperty.Register(
- nameof(StrokeStartLineCap),
- typeof(PenLineCap),
- typeof(Arc),
- new PropertyMetadata(PenLineCap.Round, PropertyChangedCallback)
- );
+ static Arc()
+ {
+ // Modify the metadata of the StrokeStartLineCap dependency property.
+ StrokeStartLineCapProperty.OverrideMetadata(
+ typeof(Arc),
+ new FrameworkPropertyMetadata(PenLineCap.Round, PropertyChangedCallback)
+ );
+ }
///
/// Gets or sets the initial angle from which the arc will be drawn.
@@ -87,13 +88,6 @@ public SweepDirection SweepDirection
set => SetValue(SweepDirectionProperty, value);
}
- // TODO: Should we?
- public new PenLineCap StrokeStartLineCap
- {
- get { return (PenLineCap)GetValue(StrokeStartLineCapProperty); }
- set { SetValue(StrokeStartLineCapProperty, value); }
- }
-
///
/// Gets a value indicating whether one of the two larger arc sweeps is chosen; otherwise, if is , one of the smaller arc sweeps is chosen.
///
@@ -235,12 +229,11 @@ protected override Size ArrangeOverride(Size finalSize)
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
- Pen pen =
- new(Stroke, StrokeThickness)
- {
- StartLineCap = StrokeStartLineCap,
- EndLineCap = StrokeStartLineCap
- };
+ Pen pen = new(Stroke, StrokeThickness)
+ {
+ StartLineCap = StrokeStartLineCap,
+ EndLineCap = StrokeStartLineCap,
+ };
drawingContext.DrawGeometry(Stroke, pen, DefinedGeometry());
}
diff --git a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.cs b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.cs
index fb8a326dc..3f84f446d 100644
--- a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.cs
+++ b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.cs
@@ -7,8 +7,8 @@
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
+using Windows.Win32;
using Wpf.Ui.Input;
-using Wpf.Ui.Interop;
// ReSharper disable once CheckNamespace
namespace Wpf.Ui.Controls;
@@ -30,7 +30,7 @@ namespace Wpf.Ui.Controls;
[TemplatePart(Name = ElementTextBox, Type = typeof(TextBox))]
[TemplatePart(Name = ElementSuggestionsPopup, Type = typeof(Popup))]
[TemplatePart(Name = ElementSuggestionsList, Type = typeof(ListView))]
-public class AutoSuggestBox : System.Windows.Controls.ItemsControl, IIconControl
+public class AutoSuggestBox : ItemsControl, IIconControl
{
protected const string ElementTextBox = "PART_TextBox";
protected const string ElementSuggestionsPopup = "PART_SuggestionsPopup";
@@ -100,6 +100,14 @@ public class AutoSuggestBox : System.Windows.Controls.ItemsControl, IIconControl
new PropertyMetadata(null)
);
+ /// Identifies the dependency property.
+ public static readonly DependencyProperty ClearButtonEnabledProperty = DependencyProperty.Register(
+ nameof(ClearButtonEnabled),
+ typeof(bool),
+ typeof(AutoSuggestBox),
+ new PropertyMetadata(false)
+ );
+
///
/// Gets or sets your items here if you want to use the default filtering
///
@@ -169,6 +177,15 @@ public IconElement? Icon
set => SetValue(IconProperty, value);
}
+ ///
+ /// Gets or sets a value indicating whether to show the clear button when is focused.
+ ///
+ public bool ClearButtonEnabled
+ {
+ get => (bool)GetValue(ClearButtonEnabledProperty);
+ set => SetValue(ClearButtonEnabledProperty, value);
+ }
+
///
/// Gets command used for focusing control.
///
@@ -358,7 +375,7 @@ protected virtual void OnQuerySubmitted(string queryText)
{
var args = new AutoSuggestBoxQuerySubmittedEventArgs(QuerySubmittedEvent, this)
{
- QueryText = queryText
+ QueryText = queryText,
};
RaiseEvent(args);
@@ -372,7 +389,7 @@ protected virtual void OnSuggestionChosen(object selectedItem)
{
var args = new AutoSuggestBoxSuggestionChosenEventArgs(SuggestionChosenEvent, this)
{
- SelectedItem = selectedItem
+ SelectedItem = selectedItem,
};
RaiseEvent(args);
@@ -393,7 +410,7 @@ protected virtual void OnTextChanged(AutoSuggestionBoxTextChangeReason reason, s
var args = new AutoSuggestBoxTextChangedEventArgs(TextChangedEvent, this)
{
Reason = reason,
- Text = text
+ Text = text,
};
RaiseEvent(args);
@@ -517,9 +534,9 @@ private IntPtr Hook(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool
return IntPtr.Zero;
}
- var message = (User32.WM)msg;
+ var message = (uint)msg;
- if (message is User32.WM.NCACTIVATE or User32.WM.WINDOWPOSCHANGED)
+ if (message is PInvoke.WM_NCACTIVATE or PInvoke.WM_WINDOWPOSCHANGED)
{
SetCurrentValue(IsSuggestionListOpenProperty, false);
}
@@ -551,13 +568,15 @@ private void DefaultFiltering(string text)
return;
}
- var splitText = text.ToLowerInvariant().Split(' ');
+ var splitText = text.Split(' ');
var suitableItems = OriginalItemsSource
.Cast()
.Where(item =>
{
- var itemText = GetStringFromObj(item)?.ToLowerInvariant();
- return splitText.All(key => itemText?.Contains(key) ?? false);
+ var itemText = GetStringFromObj(item);
+ return splitText.All(key =>
+ itemText?.Contains(key, StringComparison.OrdinalIgnoreCase) ?? false
+ );
})
.ToList();
diff --git a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml
index 5465b4a70..446d7f002 100644
--- a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml
+++ b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml
@@ -92,6 +92,8 @@
+
+
diff --git a/src/Wpf.Ui/Controls/Calendar/Calendar.xaml b/src/Wpf.Ui/Controls/Calendar/Calendar.xaml
index b4948930d..c287cf894 100644
--- a/src/Wpf.Ui/Controls/Calendar/Calendar.xaml
+++ b/src/Wpf.Ui/Controls/Calendar/Calendar.xaml
@@ -19,9 +19,14 @@
+
+
+
+
-
+ BorderThickness="0"
+ Focusable="True"
+ Foreground="{DynamicResource CalendarViewNavigationButtonForeground}"
+ MouseOverBackground="{DynamicResource CalendarViewItemBackgroundPointerOver}"
+ PressedBackground="{DynamicResource CalendarViewItemBackgroundPressed}">
+
-
+ FontSize="16"
+ Symbol="CaretDown16">
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -487,9 +554,11 @@
-
-
-
+
+
+
+
+
@@ -497,19 +566,19 @@
x:Name="PART_Root"
Margin="0"
Padding="0"
- Background="{DynamicResource CalendarViewBackground}"
- BorderBrush="{DynamicResource CalendarViewBorderBrush}"
- BorderThickness="1"
- CornerRadius="8">
+ Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ CornerRadius="4">
@@ -517,6 +586,47 @@
+
+
diff --git a/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.cs b/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.cs
index 1267a64c0..9576843f3 100644
--- a/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.cs
+++ b/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.cs
@@ -117,7 +117,7 @@ private void InitializePopup()
{
Source = this,
Mode = BindingMode.TwoWay,
- UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
}
);
_ = calendar.SetBinding(
@@ -126,7 +126,7 @@ private void InitializePopup()
{
Source = this,
Mode = BindingMode.TwoWay,
- UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
}
);
_ = calendar.SetBinding(
@@ -135,7 +135,7 @@ private void InitializePopup()
{
Source = this,
Mode = BindingMode.TwoWay,
- UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
}
);
@@ -151,7 +151,7 @@ private void InitializePopup()
VerticalOffset = 1D,
VerticalAlignment = VerticalAlignment.Center,
PopupAnimation = PopupAnimation.None,
- AllowsTransparency = true
+ AllowsTransparency = true,
};
_ = _popup.SetBinding(
@@ -160,7 +160,7 @@ private void InitializePopup()
{
Source = this,
Mode = BindingMode.TwoWay,
- UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
}
);
}
diff --git a/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.xaml b/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.xaml
index bf23e745b..90bcd6dd3 100644
--- a/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.xaml
+++ b/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.xaml
@@ -17,17 +17,17 @@
+
+
-
\ No newline at end of file
diff --git a/src/Wpf.Ui/Controls/CardAction/CardAction.cs b/src/Wpf.Ui/Controls/CardAction/CardAction.cs
index dc73e9189..dac6f7554 100644
--- a/src/Wpf.Ui/Controls/CardAction/CardAction.cs
+++ b/src/Wpf.Ui/Controls/CardAction/CardAction.cs
@@ -4,6 +4,8 @@
// All Rights Reserved.
// ReSharper disable once CheckNamespace
+using System.Windows.Automation.Peers;
+
namespace Wpf.Ui.Controls;
///
@@ -48,4 +50,9 @@ public IconElement? Icon
get => (IconElement?)GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
+
+ protected override AutomationPeer OnCreateAutomationPeer()
+ {
+ return new CardActionAutomationPeer(this);
+ }
}
diff --git a/src/Wpf.Ui/Controls/CardAction/CardActionAutomationPeer.cs b/src/Wpf.Ui/Controls/CardAction/CardActionAutomationPeer.cs
new file mode 100644
index 000000000..ffba11b5f
--- /dev/null
+++ b/src/Wpf.Ui/Controls/CardAction/CardActionAutomationPeer.cs
@@ -0,0 +1,77 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Automation;
+using System.Windows.Automation.Peers;
+
+namespace Wpf.Ui.Controls;
+
+internal class CardActionAutomationPeer : FrameworkElementAutomationPeer
+{
+ private readonly CardAction _owner;
+
+ public CardActionAutomationPeer(CardAction owner)
+ : base(owner)
+ {
+ _owner = owner;
+ }
+
+ protected override string GetClassNameCore()
+ {
+ return "Button";
+ }
+
+ protected override AutomationControlType GetAutomationControlTypeCore()
+ {
+ return AutomationControlType.Button;
+ }
+
+ public override object GetPattern(PatternInterface patternInterface)
+ {
+ if (patternInterface == PatternInterface.ItemContainer)
+ {
+ return this;
+ }
+
+ return base.GetPattern(patternInterface);
+ }
+
+ protected override AutomationPeer GetLabeledByCore()
+ {
+ if (_owner.Content is UIElement element)
+ {
+ return CreatePeerForElement(element);
+ }
+
+ return base.GetLabeledByCore();
+ }
+
+ protected override string GetNameCore()
+ {
+ var result = base.GetNameCore() ?? string.Empty;
+
+ if (result == string.Empty)
+ {
+ result = AutomationProperties.GetName(_owner);
+ }
+
+ if (result == string.Empty && _owner.Content is DependencyObject d)
+ {
+ result = AutomationProperties.GetName(d);
+ }
+
+ if (result == string.Empty && _owner.Content is string s)
+ {
+ result = s;
+ }
+
+ return result;
+ }
+}
diff --git a/src/Wpf.Ui/Controls/CardControl/CardControl.xaml b/src/Wpf.Ui/Controls/CardControl/CardControl.xaml
index 1c33c7e63..6d7693529 100644
--- a/src/Wpf.Ui/Controls/CardControl/CardControl.xaml
+++ b/src/Wpf.Ui/Controls/CardControl/CardControl.xaml
@@ -86,24 +86,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Wpf.Ui/Controls/CardExpander/CardExpander.xaml b/src/Wpf.Ui/Controls/CardExpander/CardExpander.xaml
index 25d1836db..0f66c757b 100644
--- a/src/Wpf.Ui/Controls/CardExpander/CardExpander.xaml
+++ b/src/Wpf.Ui/Controls/CardExpander/CardExpander.xaml
@@ -13,7 +13,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Wpf.Ui.Controls"
xmlns:converters="clr-namespace:Wpf.Ui.Converters"
- xmlns:system="clr-namespace:System;assembly=System.Runtime">
+ xmlns:system="clr-namespace:System;assembly=System.Runtime"
+ xmlns:animations="clr-namespace:Wpf.Ui.Animations">
14,16,14,16
1
@@ -24,34 +25,36 @@
16.0
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -105,6 +108,7 @@
+
@@ -119,8 +123,13 @@
Grid.Row="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
- BorderThickness="1"
- CornerRadius="{TemplateBinding CornerRadius}">
+ BorderThickness="1">
+
+
+
+
+
+
+
+
+
+
+
+
-
- 0.0
-
-
+
@@ -197,14 +208,13 @@
-
-
+
-
+
11,5,11,6
1
8,0,0,0
- 14
- 22
- 22
+ 13
+ 20
+ 20
+ 00:00:00.250
+ 00:00:00.250
+
+
-
-
-
-
-
-
- #FFFF0000
+
- 11,5,11,6
- 1
- 8,0,0,0
- 14
- 22
- 22
+
-
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui/Controls/DatePicker/DatePicker.xaml b/src/Wpf.Ui/Controls/DatePicker/DatePicker.xaml
index c7e7415b2..2ed4c77b8 100644
--- a/src/Wpf.Ui/Controls/DatePicker/DatePicker.xaml
+++ b/src/Wpf.Ui/Controls/DatePicker/DatePicker.xaml
@@ -1,4 +1,4 @@
-īģŋ
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
@@ -470,16 +547,15 @@
-
+ Opacity="0.135"
+ ShadowDepth="10"
+ Color="#202020" />
@@ -530,16 +607,32 @@
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -583,7 +676,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
@@ -627,7 +736,7 @@
@@ -661,7 +770,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -709,7 +836,7 @@
-
+
@@ -737,7 +864,7 @@
@@ -792,8 +919,9 @@
+ Opacity="0.135"
+ ShadowDepth="10"
+ Color="#202020" />
@@ -801,12 +929,28 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui/Controls/MessageBox/MessageBox.cs b/src/Wpf.Ui/Controls/MessageBox/MessageBox.cs
index 0e37bcb1e..48b59cfb3 100644
--- a/src/Wpf.Ui/Controls/MessageBox/MessageBox.cs
+++ b/src/Wpf.Ui/Controls/MessageBox/MessageBox.cs
@@ -115,6 +115,14 @@ public class MessageBox : System.Windows.Window
new PropertyMetadata(true)
);
+ /// Identifies the dependency property.
+ public static readonly DependencyProperty IsCloseButtonEnabledProperty = DependencyProperty.Register(
+ nameof(IsCloseButtonEnabled),
+ typeof(bool),
+ typeof(MessageBox),
+ new PropertyMetadata(true)
+ );
+
/// Identifies the dependency property.
public static readonly DependencyProperty TemplateButtonCommandProperty = DependencyProperty.Register(
nameof(TemplateButtonCommand),
@@ -214,7 +222,16 @@ public ControlAppearance CloseButtonAppearance
}
///
- /// Gets or sets a value indicating whether the primary button is enabled.
+ /// Gets or sets a value indicating whether the close button is enabled.
+ ///
+ public bool IsCloseButtonEnabled
+ {
+ get => (bool)GetValue(IsCloseButtonEnabledProperty);
+ set => SetValue(IsCloseButtonEnabledProperty, value);
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the secondary button is enabled.
///
public bool IsSecondaryButtonEnabled
{
@@ -223,7 +240,7 @@ public bool IsSecondaryButtonEnabled
}
///
- /// Gets or sets a value indicating whether the secondary button is enabled.
+ /// Gets or sets a value indicating whether the primary button is enabled.
///
public bool IsPrimaryButtonEnabled
{
@@ -236,10 +253,12 @@ public bool IsPrimaryButtonEnabled
///
public IRelayCommand TemplateButtonCommand => (IRelayCommand)GetValue(TemplateButtonCommandProperty);
+#if !NET8_0_OR_GREATER
private static readonly PropertyInfo CanCenterOverWPFOwnerPropertyInfo = typeof(Window).GetProperty(
"CanCenterOverWPFOwner",
BindingFlags.NonPublic | BindingFlags.Instance
)!;
+#endif
///
/// Initializes a new instance of the class.
@@ -335,10 +354,7 @@ protected virtual void OnLoaded()
CenterWindowOnScreen();
break;
case WindowStartupLocation.CenterOwner:
- if (
- !CanCenterOverWPFOwner()
- || Owner.WindowState is WindowState.Maximized or WindowState.Minimized
- )
+ if (!CanCenterOverWPFOwner() || Owner.WindowState is WindowState.Minimized)
{
CenterWindowOnScreen();
}
@@ -426,7 +442,7 @@ protected virtual void OnButtonClick(MessageBoxButton button)
{
MessageBoxButton.Primary => MessageBoxResult.Primary,
MessageBoxButton.Secondary => MessageBoxResult.Secondary,
- _ => MessageBoxResult.None
+ _ => MessageBoxResult.None,
};
_ = Tcs?.TrySetResult(result);
diff --git a/src/Wpf.Ui/Controls/MessageBox/MessageBox.xaml b/src/Wpf.Ui/Controls/MessageBox/MessageBox.xaml
index de5f9245a..b3537d189 100644
--- a/src/Wpf.Ui/Controls/MessageBox/MessageBox.xaml
+++ b/src/Wpf.Ui/Controls/MessageBox/MessageBox.xaml
@@ -8,13 +8,17 @@
+ xmlns:controls="clr-namespace:Wpf.Ui.Controls"
+ xmlns:converters="clr-namespace:Wpf.Ui.Converters">
+
+
-
+
@@ -232,7 +232,7 @@
-
+
diff --git a/src/Wpf.Ui/Controls/ScrollDirection.cs b/src/Wpf.Ui/Controls/ScrollDirection.cs
index c9008cbe9..41063031e 100644
--- a/src/Wpf.Ui/Controls/ScrollDirection.cs
+++ b/src/Wpf.Ui/Controls/ScrollDirection.cs
@@ -25,5 +25,5 @@ public enum ScrollDirection
///
/// Horizontal scroll direction.
///
- Horizontal
+ Horizontal,
}
diff --git a/src/Wpf.Ui/Controls/Snackbar/SnackbarPresenter.cs b/src/Wpf.Ui/Controls/Snackbar/SnackbarPresenter.cs
index aba5a764e..0e5db4be1 100644
--- a/src/Wpf.Ui/Controls/Snackbar/SnackbarPresenter.cs
+++ b/src/Wpf.Ui/Controls/Snackbar/SnackbarPresenter.cs
@@ -77,7 +77,7 @@ public virtual void AddToQue(Snackbar snackbar)
if (Content is null)
{
- ShowQueuedSnackbars(); // TODO: Fix detached process
+ _ = ShowQueuedSnackbarsAsync(); // TODO: Fix detached process
}
}
@@ -86,7 +86,7 @@ public virtual async Task ImmediatelyDisplay(Snackbar snackbar)
await HideCurrent();
await ShowSnackbar(snackbar);
- await ShowQueuedSnackbars();
+ await ShowQueuedSnackbarsAsync();
}
public virtual async Task HideCurrent()
@@ -101,7 +101,7 @@ public virtual async Task HideCurrent()
ResetCancellationTokenSource();
}
- private async Task ShowQueuedSnackbars()
+ private async Task ShowQueuedSnackbarsAsync()
{
while (Queue.Count > 0 && !CancellationTokenSource.IsCancellationRequested)
{
diff --git a/src/Wpf.Ui/Controls/SpacingMode.cs b/src/Wpf.Ui/Controls/SpacingMode.cs
index 154af3605..2d4fbea04 100644
--- a/src/Wpf.Ui/Controls/SpacingMode.cs
+++ b/src/Wpf.Ui/Controls/SpacingMode.cs
@@ -34,5 +34,5 @@ public enum SpacingMode
///
/// The remaining space is evenly distributed between start and end of each row.
///
- StartAndEndOnly
+ StartAndEndOnly,
}
diff --git a/src/Wpf.Ui/Controls/SplitButton/SplitButton.cs b/src/Wpf.Ui/Controls/SplitButton/SplitButton.cs
index 8d2e4aac4..66c63ca27 100644
--- a/src/Wpf.Ui/Controls/SplitButton/SplitButton.cs
+++ b/src/Wpf.Ui/Controls/SplitButton/SplitButton.cs
@@ -5,6 +5,7 @@
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
+using System.Windows.Input;
// ReSharper disable once CheckNamespace
namespace Wpf.Ui.Controls;
@@ -12,9 +13,12 @@ namespace Wpf.Ui.Controls;
///
/// Represents a button with two parts that can be invoked separately. One part behaves like a standard button and the other part invokes a flyout.
///
+[TemplatePart(Name = TemplateElementToggle, Type = typeof(Border))]
[TemplatePart(Name = TemplateElementToggleButton, Type = typeof(ToggleButton))]
-public class SplitButton : Wpf.Ui.Controls.Button
+public class SplitButton : Button
{
+ private const string TemplateElementToggle = "PART_Toggle";
+
///
/// Template element represented by the ToggleButton name.
///
@@ -25,7 +29,9 @@ public class SplitButton : Wpf.Ui.Controls.Button
///
/// Gets or sets control responsible for toggling the drop-down button.
///
- protected ToggleButton SplitButtonToggleButton { get; set; } = null!;
+ protected ToggleButton? SplitButtonToggleButton { get; set; }
+
+ private Border? _splitButtonToggleBorder;
/// Identifies the dependency property.
public static readonly DependencyProperty FlyoutProperty = DependencyProperty.Register(
@@ -75,6 +81,25 @@ public SplitButton()
self.ReleaseTemplateResources();
};
+ Loaded += static (sender, _) =>
+ {
+ var self = (SplitButton)sender;
+ if (self.SplitButtonToggleButton != null)
+ {
+ self.AttachToggleButtonClick();
+ }
+ };
+ }
+
+ private void AttachToggleButtonClick()
+ {
+ if (SplitButtonToggleButton != null)
+ {
+ SplitButtonToggleButton.PreviewMouseLeftButtonUp -=
+ OnSplitButtonToggleButtonOnPreviewMouseLeftButtonUp;
+ SplitButtonToggleButton.PreviewMouseLeftButtonUp +=
+ OnSplitButtonToggleButtonOnPreviewMouseLeftButtonUp;
+ }
}
private static void OnFlyoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -127,9 +152,7 @@ public override void OnApplyTemplate()
if (GetTemplateChild(TemplateElementToggleButton) is ToggleButton toggleButton)
{
SplitButtonToggleButton = toggleButton;
-
- SplitButtonToggleButton.Click -= OnSplitButtonToggleButtonOnClick;
- SplitButtonToggleButton.Click += OnSplitButtonToggleButtonOnClick;
+ AttachToggleButtonClick();
}
else
{
@@ -137,6 +160,11 @@ public override void OnApplyTemplate()
$"Element {nameof(TemplateElementToggleButton)} of type {typeof(ToggleButton)} not found in {typeof(SplitButton)}"
);
}
+
+ if (GetTemplateChild(TemplateElementToggle) is Border toggleBorder)
+ {
+ _splitButtonToggleBorder = toggleBorder;
+ }
}
///
@@ -144,22 +172,31 @@ public override void OnApplyTemplate()
///
protected virtual void ReleaseTemplateResources()
{
- SplitButtonToggleButton.Click -= OnSplitButtonToggleButtonOnClick;
+ if (SplitButtonToggleButton != null)
+ {
+ SplitButtonToggleButton.PreviewMouseLeftButtonUp -=
+ OnSplitButtonToggleButtonOnPreviewMouseLeftButtonUp;
+ }
}
- private void OnSplitButtonToggleButtonOnClick(object sender, RoutedEventArgs e)
+ private void OnSplitButtonToggleButtonOnPreviewMouseLeftButtonUp(object sender, MouseEventArgs e)
{
- if (sender is not ToggleButton || _contextMenu is null)
+ if (sender is not ToggleButton || _contextMenu is null || _splitButtonToggleBorder is null)
+ {
+ return;
+ }
+
+ // Ensure mouse up actually happened inside the toggler, and not outside.
+ var position = e.GetPosition(_splitButtonToggleBorder);
+ HitTestResult hitTestResult = VisualTreeHelper.HitTest(_splitButtonToggleBorder, position);
+ if (hitTestResult?.VisualHit == null)
{
return;
}
_contextMenu.SetCurrentValue(MinWidthProperty, ActualWidth);
_contextMenu.SetCurrentValue(ContextMenu.PlacementTargetProperty, this);
- _contextMenu.SetCurrentValue(
- ContextMenu.PlacementProperty,
- System.Windows.Controls.Primitives.PlacementMode.Bottom
- );
+ _contextMenu.SetCurrentValue(ContextMenu.PlacementProperty, PlacementMode.Bottom);
_contextMenu.SetCurrentValue(ContextMenu.IsOpenProperty, true);
}
}
diff --git a/src/Wpf.Ui/Controls/SplitButton/SplitButton.xaml b/src/Wpf.Ui/Controls/SplitButton/SplitButton.xaml
index 609d86275..da51063ca 100644
--- a/src/Wpf.Ui/Controls/SplitButton/SplitButton.xaml
+++ b/src/Wpf.Ui/Controls/SplitButton/SplitButton.xaml
@@ -42,6 +42,7 @@
@@ -85,9 +84,11 @@
+ Style="{DynamicResource DefaultSplitButtonToggleButtonStyle}">
@@ -142,19 +145,35 @@
-
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
diff --git a/src/Wpf.Ui/Controls/SymbolFilled.cs b/src/Wpf.Ui/Controls/SymbolFilled.cs
index 331f8e9a8..59b4456c9 100644
--- a/src/Wpf.Ui/Controls/SymbolFilled.cs
+++ b/src/Wpf.Ui/Controls/SymbolFilled.cs
@@ -6,9 +6,10 @@
namespace Wpf.Ui.Controls;
///
-/// Represents a list of filled Fluent System Icons v.1.1.233.
+/// Represents a list of filled Fluent System Icons v.1.1.271.
/// May be converted to using GetGlyph() or to using GetString()
///
+#pragma warning disable CS1591
public enum SymbolFilled
{
///
@@ -7824,4 +7825,595 @@ public enum SymbolFilled
SpatulaSpoon28 = 0xF0612,
SpatulaSpoon32 = 0xF0613,
SpatulaSpoon48 = 0xF0614,
+ AppsSettings16 = 0xF0615,
+ AppsSettings20 = 0xF0616,
+ AppsShield16 = 0xF0617,
+ AppsShield20 = 0xF0618,
+ ArrowUpload32 = 0xF0619,
+ CalendarEdit32 = 0xF061A,
+ DataBarVerticalArrowDown16 = 0xF061B,
+ DataBarVerticalArrowDown20 = 0xF061C,
+ DataBarVerticalArrowDown24 = 0xF061D,
+ HapticStrong16 = 0xF061E,
+ HapticStrong20 = 0xF061F,
+ HapticStrong24 = 0xF0620,
+ HapticWeak16 = 0xF0621,
+ HapticWeak20 = 0xF0622,
+ HapticWeak24 = 0xF0623,
+ HexagonSparkle20 = 0xF0624,
+ HexagonSparkle24 = 0xF0625,
+ MailEdit32 = 0xF0626,
+ Password32 = 0xF0627,
+ Password48 = 0xF0628,
+ PasswordClock48 = 0xF0629,
+ PasswordReset48 = 0xF062A,
+ PeopleEye16 = 0xF062B,
+ PeopleEye20 = 0xF062C,
+ PinGlobe16 = 0xF062D,
+ PinGlobe20 = 0xF062E,
+ Run28 = 0xF062F,
+ Run32 = 0xF0630,
+ Run48 = 0xF0631,
+ TabGroup16 = 0xF0632,
+ TabGroup20 = 0xF0633,
+ TabGroup24 = 0xF0634,
+ Book28 = 0xF0635,
+ Book48 = 0xF0636,
+ CameraArrowUp16 = 0xF0637,
+ CameraArrowUp20 = 0xF0638,
+ CameraArrowUp24 = 0xF0639,
+ ChatSettings16 = 0xF063A,
+ CircleHighlight20 = 0xF063B,
+ CircleHighlight24 = 0xF063C,
+ CircleHint24 = 0xF063D,
+ CircleShadow20 = 0xF063E,
+ CircleShadow24 = 0xF063F,
+ ContentView16 = 0xF0640,
+ DoubleTapSwipeDown16 = 0xF0641,
+ DoubleTapSwipeUp16 = 0xF0642,
+ FlashSparkle16 = 0xF0643,
+ LocationRipple12 = 0xF0644,
+ SearchSquare16 = 0xF0645,
+ SettingsChat16 = 0xF0646,
+ ShareMultiple16 = 0xF0647,
+ ShareMultiple20 = 0xF0648,
+ ShareMultiple24 = 0xF0649,
+ SlidePlay20 = 0xF064A,
+ SlidePlay24 = 0xF064B,
+ ArrowTurnRight16 = 0xF064C,
+ ChartMultiple16 = 0xF064D,
+ Column24 = 0xF064E,
+ DataPie16 = 0xF064F,
+ LayoutColumnTwo32 = 0xF0650,
+ LayoutRowTwo32 = 0xF0653,
+ MailCopy32 = 0xF0655,
+ PaintBrushSparkle20 = 0xF0656,
+ PaintBrushSparkle24 = 0xF0657,
+ PeopleCommunity12 = 0xF0658,
+ PersonBoard12 = 0xF0659,
+ PersonTentative16 = 0xF065A,
+ PersonTentative20 = 0xF065B,
+ PersonTentative24 = 0xF065C,
+ TabDesktopSearch16 = 0xF065D,
+ TabDesktopSearch20 = 0xF065E,
+ TabDesktopSearch24 = 0xF065F,
+ TableSparkle20 = 0xF0660,
+ TableSparkle24 = 0xF0661,
+ Comment32 = 0xF0662,
+ CommentAdd32 = 0xF0663,
+ CropArrowRotate16 = 0xF0664,
+ CropArrowRotate20 = 0xF0665,
+ CropArrowRotate24 = 0xF0666,
+ DesktopOff20 = 0xF0667,
+ DesktopOff24 = 0xF0668,
+ Food28 = 0xF0669,
+ Food32 = 0xF066A,
+ Food48 = 0xF066B,
+ LayerDiagonalAdd24 = 0xF066C,
+ MailAlert32 = 0xF066D,
+ MailArrowClockwise32 = 0xF066E,
+ PersonSupport32 = 0xF066F,
+ TagOff16 = 0xF0670,
+ TextColumnOneWideLightning16 = 0xF0671,
+ WalletCreditCard28 = 0xF0672,
+ WalletCreditCard48 = 0xF0673,
+ BreakoutRoom32 = 0xF0674,
+ CardUiPortraitFlip16 = 0xF0675,
+ CardUiPortraitFlip20 = 0xF0676,
+ CardUiPortraitFlip24 = 0xF0677,
+ Cursor28 = 0xF0678,
+ Cursor32 = 0xF0679,
+ LayoutRowTwo28 = 0xF067A,
+ LayoutRowTwo48 = 0xF067B,
+ NotepadSparkle16 = 0xF067C,
+ NotepadSparkle20 = 0xF067D,
+ NotepadSparkle24 = 0xF067E,
+ NotepadSparkle28 = 0xF067F,
+ NotepadSparkle32 = 0xF0680,
+ PaintBrush28 = 0xF0681,
+ PaintBrushSubtract16 = 0xF0682,
+ PaintBrushSubtract20 = 0xF0683,
+ PaintBrushSubtract24 = 0xF0684,
+ PaintBrushSubtract28 = 0xF0685,
+ PaintBrushSubtract32 = 0xF0686,
+ PlayCircleSparkle16 = 0xF0687,
+ PlayCircleSparkle20 = 0xF0688,
+ PlayCircleSparkle24 = 0xF0689,
+ Replay16 = 0xF068A,
+ Replay24 = 0xF068B,
+ Replay28 = 0xF068C,
+ Replay32 = 0xF068D,
+ SendPerson16 = 0xF068E,
+ SendPerson20 = 0xF068F,
+ SendPerson24 = 0xF0690,
+ SquareDovetailJoint12 = 0xF0691,
+ SquareDovetailJoint16 = 0xF0692,
+ SquareDovetailJoint20 = 0xF0693,
+ SquareDovetailJoint24 = 0xF0694,
+ SquareDovetailJoint28 = 0xF0695,
+ SquareDovetailJoint32 = 0xF0696,
+ SquareDovetailJoint48 = 0xF0697,
+ TableCursor16 = 0xF0698,
+ TableCursor20 = 0xF0699,
+ TableCursor24 = 0xF069A,
+ TransparencySquare20 = 0xF069B,
+ TransparencySquare24 = 0xF069C,
+ ArrowCollapseAll16 = 0xF069D,
+ ArrowExpandAll16 = 0xF069E,
+ ArrowExpandAll20 = 0xF069F,
+ ArrowExpandAll24 = 0xF06A0,
+ ChatArrowBackDown16 = 0xF06A1,
+ ChatArrowBackDown20 = 0xF06A2,
+ ChatArrowBackDown24 = 0xF06A3,
+ ChatArrowBackDown28 = 0xF06A4,
+ ChatArrowBackDown32 = 0xF06A5,
+ ChatArrowBackDown48 = 0xF06A6,
+ DesktopArrowDown32 = 0xF06A7,
+ EditLineHorizontal320 = 0xF06A8,
+ EditLineHorizontal324 = 0xF06A9,
+ GiftOpen32 = 0xF06AA,
+ Prompt16 = 0xF06AB,
+ Prompt20 = 0xF06AC,
+ Prompt24 = 0xF06AD,
+ Prompt28 = 0xF06AE,
+ Prompt32 = 0xF06AF,
+ Prompt48 = 0xF06B0,
+ SearchSparkle16 = 0xF06B1,
+ SearchSparkle20 = 0xF06B2,
+ SearchSparkle24 = 0xF06B3,
+ SearchSparkle28 = 0xF06B4,
+ SearchSparkle32 = 0xF06B5,
+ SearchSparkle48 = 0xF06B6,
+ SlideTextCall16 = 0xF06B7,
+ SlideTextCall20 = 0xF06B8,
+ SlideTextCall24 = 0xF06B9,
+ SlideTextCall28 = 0xF06BA,
+ SlideTextCall48 = 0xF06BB,
+ SlideTextCursor20 = 0xF06BC,
+ SlideTextCursor24 = 0xF06BD,
+ VehicleMotorcycle16 = 0xF06BE,
+ VehicleMotorcycle20 = 0xF06BF,
+ VehicleMotorcycle24 = 0xF06C0,
+ VehicleMotorcycle28 = 0xF06C1,
+ VehicleMotorcycle32 = 0xF06C2,
+ VehicleMotorcycle48 = 0xF06C3,
+ AccessibilityMore16 = 0xF06C4,
+ AccessibilityMore20 = 0xF06C5,
+ AccessibilityMore24 = 0xF06C6,
+ Battery028 = 0xF06C7,
+ Battery032 = 0xF06C8,
+ Battery128 = 0xF06C9,
+ Battery132 = 0xF06CA,
+ Battery1028 = 0xF06CB,
+ Battery1032 = 0xF06CC,
+ Battery228 = 0xF06CD,
+ Battery232 = 0xF06CE,
+ Battery328 = 0xF06CF,
+ Battery332 = 0xF06D0,
+ Battery428 = 0xF06D1,
+ Battery432 = 0xF06D2,
+ Battery528 = 0xF06D3,
+ Battery532 = 0xF06D4,
+ Battery628 = 0xF06D5,
+ Battery632 = 0xF06D6,
+ Battery728 = 0xF06D7,
+ Battery732 = 0xF06D8,
+ Battery828 = 0xF06D9,
+ Battery832 = 0xF06DA,
+ Battery928 = 0xF06DB,
+ Battery932 = 0xF06DC,
+ BatteryCharge28 = 0xF06DD,
+ BatteryCharge32 = 0xF06DE,
+ CoinStack16 = 0xF06DF,
+ CoinStack20 = 0xF06E0,
+ CoinStack24 = 0xF06E1,
+ DatabaseArrowUp16 = 0xF06E2,
+ PaintBrush12 = 0xF06E7,
+ PanelRight12 = 0xF06E8,
+ PeopleEdit32 = 0xF06E9,
+ PersonMail32 = 0xF06EA,
+ PuzzlePiece12 = 0xF06EB,
+ GameChat20 = 0xF06EC,
+ PersonHome16 = 0xF06ED,
+ PersonHome20 = 0xF06EE,
+ PersonHome24 = 0xF06EF,
+ PersonHome28 = 0xF06F0,
+ PersonHome32 = 0xF06F1,
+ PersonHome48 = 0xF06F2,
+ Teaching20 = 0xF06F3,
+ EditLock16 = 0xF06F4,
+ EditLock20 = 0xF06F5,
+ EditLock24 = 0xF06F6,
+ LayoutRowTwoSettings20 = 0xF06F7,
+ LayoutRowTwoSettings24 = 0xF06F8,
+ LayoutRowTwoSettings28 = 0xF06F9,
+ LayoutRowTwoSettings32 = 0xF06FA,
+ ShieldAdd28 = 0xF06FB,
+ ShieldAdd32 = 0xF06FC,
+ ShieldAdd48 = 0xF06FD,
+ ShieldCheckmark32 = 0xF06FE,
+ ShieldTask32 = 0xF06FF,
+ Toolbox32 = 0xF0700,
+ WarningLockOpen16 = 0xF0701,
+ WarningLockOpen20 = 0xF0702,
+ WarningLockOpen24 = 0xF0703,
+ PersonBoardAdd20 = 0xF0704,
+ PersonSquareAdd16 = 0xF0705,
+ PersonSquareAdd20 = 0xF0706,
+ PersonSquareAdd24 = 0xF0707,
+ Airplane16 = 0xF0708,
+ Airplane28 = 0xF0709,
+ Airplane32 = 0xF070A,
+ Airplane48 = 0xF070B,
+ GlobeOff12 = 0xF070C,
+ GlobeOff16 = 0xF070D,
+ GlobeOff20 = 0xF070E,
+ GlobeOff24 = 0xF070F,
+ GlobeOff28 = 0xF0710,
+ GlobeOff32 = 0xF0711,
+ GlobeOff48 = 0xF0712,
+ HatGraduation32 = 0xF0713,
+ HatGraduation48 = 0xF0714,
+ PersonBoardAdd16 = 0xF0715,
+ PersonBoardAdd24 = 0xF0716,
+ PersonBoardAdd28 = 0xF0717,
+ PersonBoardAdd32 = 0xF0718,
+ ShoppingBag28 = 0xF0719,
+ ShoppingBag32 = 0xF071A,
+ ShoppingBag48 = 0xF071B,
+ ShoppingBagTag16 = 0xF071C,
+ ShoppingBagTag28 = 0xF071D,
+ ShoppingBagTag32 = 0xF071E,
+ ShoppingBagTag48 = 0xF071F,
+ Teaching16 = 0xF0720,
+ Teaching24 = 0xF0721,
+ Teaching28 = 0xF0722,
+ Teaching32 = 0xF0723,
+ Teaching48 = 0xF0724,
+ WindowBrush20 = 0xF0725,
+ WindowBrush24 = 0xF0726,
+ WindowColumnOneFourthLeft20 = 0xF0727,
+ ArrowSyncCircle28 = 0xF072A,
+ ArrowSyncCircle32 = 0xF072B,
+ ArrowSyncCircle48 = 0xF072C,
+ CalendarArrowRepeatAll16 = 0xF072D,
+ CalendarArrowRepeatAll20 = 0xF072E,
+ CalendarArrowRepeatAll24 = 0xF072F,
+ CalendarArrowRepeatAll28 = 0xF0730,
+ CalendarArrowRepeatAll32 = 0xF0731,
+ CalendarArrowRepeatAll48 = 0xF0732,
+ CoinMultiple28 = 0xF0733,
+ CoinMultiple32 = 0xF0734,
+ CoinMultiple48 = 0xF0735,
+ BinFull48 = 0xF0736,
+ ClockToolbox32 = 0xF0737,
+ DatabaseSearch32 = 0xF0738,
+ DocumentGlobe20 = 0xF0739,
+ DocumentGlobe24 = 0xF073A,
+ FormSparkle20 = 0xF073B,
+ LineStyleSketch16 = 0xF073C,
+ LineStyleSketch20 = 0xF073D,
+ LineStyleSketch24 = 0xF073E,
+ LineStyleSketch28 = 0xF073F,
+ LineStyleSketch32 = 0xF0740,
+ Microscope32 = 0xF0741,
+ PuzzlePiece28 = 0xF0742,
+ PuzzlePiece32 = 0xF0743,
+ PuzzlePiece48 = 0xF0744,
+ Reward32 = 0xF0745,
+ TabAdd32 = 0xF0746,
+ AddCircle48 = 0xF0747,
+ ApprovalsApp48 = 0xF0748,
+ ClipboardTextEdit48 = 0xF0749,
+ DesignIdeas28 = 0xF074A,
+ DesignIdeas32 = 0xF074B,
+ DesignIdeas48 = 0xF074C,
+ DocumentFolder28 = 0xF074D,
+ DocumentFolder32 = 0xF074E,
+ DocumentFolder48 = 0xF074F,
+ EyeOff32 = 0xF0750,
+ LearningApp16 = 0xF0751,
+ Receipt48 = 0xF0752,
+ VideoBluetooth16 = 0xF0753,
+ VideoBluetooth20 = 0xF0754,
+ VideoBluetooth24 = 0xF0755,
+ VideoBluetooth28 = 0xF0756,
+ VideoBluetooth32 = 0xF0757,
+ VideoBluetooth48 = 0xF0758,
+ VideoUsb16 = 0xF0759,
+ VideoUsb20 = 0xF075A,
+ VideoUsb24 = 0xF075B,
+ VideoUsb28 = 0xF075C,
+ VideoUsb32 = 0xF075D,
+ VideoUsb48 = 0xF075E,
+ ArrowCircleUpLeft16 = 0xF075F,
+ ArrowCircleUpRight16 = 0xF0760,
+ BuildingCheckmark16 = 0xF0761,
+ BuildingCheckmark20 = 0xF0762,
+ ClockAlarm48 = 0xF0763,
+ ClothesHanger12 = 0xF0764,
+ ClothesHanger16 = 0xF0765,
+ ClothesHanger20 = 0xF0766,
+ ClothesHanger24 = 0xF0767,
+ CommentQuote16 = 0xF0768,
+ CommentQuote20 = 0xF0769,
+ CommentQuote24 = 0xF076A,
+ CommentQuote28 = 0xF076B,
+ CommentText16 = 0xF076C,
+ CommentText20 = 0xF076D,
+ CommentText24 = 0xF076E,
+ CommentText28 = 0xF076F,
+ CommentText32 = 0xF0770,
+ CommentText48 = 0xF0771,
+ Glance16 = 0xF0772,
+ Glance28 = 0xF0773,
+ Glance32 = 0xF0774,
+ Glance48 = 0xF0775,
+ GlanceHorizontal28 = 0xF0776,
+ GlanceHorizontal48 = 0xF0777,
+ Megaphone12 = 0xF0778,
+ MicLink16 = 0xF0779,
+ MicLink20 = 0xF077A,
+ MicLink24 = 0xF077B,
+ MicLink28 = 0xF077C,
+ MicLink32 = 0xF077D,
+ MicLink48 = 0xF077E,
+ PenSync16 = 0xF077F,
+ PenSync20 = 0xF0780,
+ PenSync24 = 0xF0781,
+ PenSync28 = 0xF0782,
+ PenSync32 = 0xF0783,
+ PenSync48 = 0xF0784,
+ PeopleLink16 = 0xF0785,
+ PeopleLink20 = 0xF0786,
+ PeopleLink24 = 0xF0787,
+ PeopleLink28 = 0xF0788,
+ PeopleLink32 = 0xF0789,
+ PeopleLink48 = 0xF078A,
+ PeopleQueue28 = 0xF078B,
+ PeopleQueue32 = 0xF078C,
+ PeopleQueue48 = 0xF078D,
+ PersonHeadHint16 = 0xF078E,
+ PersonHeadHint20 = 0xF078F,
+ PersonHeadHint24 = 0xF0790,
+ PersonSoundSpatial16 = 0xF0791,
+ PersonSoundSpatial20 = 0xF0792,
+ PersonSoundSpatial24 = 0xF0793,
+ PersonSoundSpatial28 = 0xF0794,
+ PersonSoundSpatial32 = 0xF0795,
+ PersonSoundSpatial48 = 0xF0796,
+ SoundWaveCircle16 = 0xF0797,
+ SoundWaveCircle28 = 0xF0798,
+ SoundWaveCircle32 = 0xF0799,
+ SoundWaveCircle48 = 0xF079A,
+ SoundWaveCircleSparkle16 = 0xF079B,
+ SoundWaveCircleSparkle20 = 0xF079C,
+ SoundWaveCircleSparkle24 = 0xF079D,
+ SoundWaveCircleSparkle28 = 0xF079E,
+ SoundWaveCircleSparkle32 = 0xF079F,
+ SoundWaveCircleSparkle48 = 0xF07A0,
+ ArrowDownRight16 = 0xF07A1,
+ ArrowDownRight20 = 0xF07A2,
+ ArrowDownRight24 = 0xF07A3,
+ ArrowDownRight32 = 0xF07A4,
+ ArrowDownRight48 = 0xF07A5,
+ ArrowRepeatAll28 = 0xF07A6,
+ ArrowRepeatAll48 = 0xF07A7,
+ Attach28 = 0xF07A8,
+ Attach48 = 0xF07A9,
+ CalendarMention16 = 0xF07AA,
+ CalendarPerson32 = 0xF07AB,
+ CommentMultipleMention16 = 0xF07AC,
+ CommentMultipleMention20 = 0xF07AD,
+ DocumentText28 = 0xF07AE,
+ DocumentText32 = 0xF07AF,
+ DocumentText48 = 0xF07B0,
+ EqualCircle16 = 0xF07B1,
+ FolderDocument16 = 0xF07B2,
+ FolderDocument20 = 0xF07B3,
+ FolderDocument24 = 0xF07B4,
+ FolderDocument28 = 0xF07B5,
+ MailInbox32 = 0xF07B6,
+ MailInboxPerson16 = 0xF07B7,
+ MailInboxPerson20 = 0xF07B8,
+ MailInboxPerson32 = 0xF07B9,
+ PlugConnected28 = 0xF07BA,
+ PlugConnected32 = 0xF07BB,
+ PlugConnected48 = 0xF07BC,
+ ArrowBounce12 = 0xF07BD,
+ ArrowBounce28 = 0xF07BE,
+ ArrowBounce48 = 0xF07BF,
+ ArrowDownLeft12 = 0xF07C0,
+ ArrowDownLeft28 = 0xF07C1,
+ ArrowFlowDiagonalUpRight12 = 0xF07C2,
+ ArrowFlowDiagonalUpRight28 = 0xF07C3,
+ ArrowFlowDiagonalUpRight48 = 0xF07C4,
+ ArrowUpRight12 = 0xF07C5,
+ ArrowUpRight28 = 0xF07C6,
+ ArrowUpRightDashes12 = 0xF07C7,
+ ArrowUpRightDashes20 = 0xF07C8,
+ ArrowUpRightDashes24 = 0xF07C9,
+ ArrowUpRightDashes28 = 0xF07CA,
+ ArrowUpRightDashes32 = 0xF07CB,
+ ArrowUpRightDashes48 = 0xF07CC,
+ ArrowWrap32 = 0xF07CD,
+ ArrowWrapUpToDown20 = 0xF07CE,
+ ArrowWrapUpToDown32 = 0xF07CF,
+ CoinMultiple16 = 0xF07D0,
+ CoinMultiple20 = 0xF07D1,
+ CoinMultiple24 = 0xF07D2,
+ CommentBadge16 = 0xF07D3,
+ CommentBadge20 = 0xF07D4,
+ CommentBadge24 = 0xF07D5,
+ DataUsage28 = 0xF07D6,
+ DataUsage32 = 0xF07D7,
+ DataUsage48 = 0xF07D8,
+ DataUsageCheckmark16 = 0xF07D9,
+ DataUsageCheckmark20 = 0xF07DA,
+ DataUsageCheckmark24 = 0xF07DB,
+ DataUsageCheckmark28 = 0xF07DC,
+ DataUsageCheckmark32 = 0xF07DD,
+ DataUsageCheckmark48 = 0xF07DE,
+ LineHorizontal1DashDotDash20 = 0xF07DF,
+ LineHorizontal1Dot20 = 0xF07E0,
+ LineHorizontal316 = 0xF07E1,
+ LineHorizontal324 = 0xF07E2,
+ LineHorizontal328 = 0xF07E3,
+ LineHorizontal332 = 0xF07E4,
+ LineHorizontal348 = 0xF07E5,
+ Navigation28 = 0xF07E6,
+ Navigation32 = 0xF07E7,
+ Navigation48 = 0xF07E8,
+ PauseCircle16 = 0xF07E9,
+ Stack28 = 0xF07EA,
+ Stack48 = 0xF07EB,
+ StackOff16 = 0xF07EC,
+ StackOff20 = 0xF07ED,
+ StackOff24 = 0xF07EE,
+ StackOff28 = 0xF07EF,
+ StackOff32 = 0xF07F0,
+ StackOff48 = 0xF07F1,
+ TextBulletListSquare28 = 0xF07F2,
+ Textbox28 = 0xF07F3,
+ Textbox32 = 0xF07F4,
+ Textbox48 = 0xF07F5,
+ TextboxCheckmark16 = 0xF07F6,
+ TextboxCheckmark20 = 0xF07F7,
+ TextboxCheckmark24 = 0xF07F8,
+ TextboxCheckmark28 = 0xF07F9,
+ TextboxCheckmark32 = 0xF07FA,
+ TextboxCheckmark48 = 0xF07FB,
+ DocumentOnePageMultipleSparkle16 = 0xF07FC,
+ DocumentOnePageMultipleSparkle20 = 0xF07FD,
+ DocumentOnePageMultipleSparkle24 = 0xF07FE,
+ AnimalPawPrint16 = 0xF07FF,
+ AnimalPawPrint20 = 0xF0800,
+ AnimalPawPrint24 = 0xF0801,
+ AnimalPawPrint28 = 0xF0802,
+ AnimalPawPrint32 = 0xF0803,
+ AnimalPawPrint48 = 0xF0804,
+ ArrowClockwiseDashes28 = 0xF0805,
+ ArrowClockwiseDashes48 = 0xF0806,
+ ArrowClockwiseDashesSettings16 = 0xF0807,
+ ArrowClockwiseDashesSettings20 = 0xF0808,
+ ArrowClockwiseDashesSettings24 = 0xF0809,
+ ArrowClockwiseDashesSettings28 = 0xF080A,
+ ArrowClockwiseDashesSettings32 = 0xF080B,
+ ArrowClockwiseDashesSettings48 = 0xF080C,
+ ChatOff16 = 0xF080D,
+ Connected24 = 0xF080E,
+ Connected32 = 0xF080F,
+ SquareTextArrowRepeatAll16 = 0xF0810,
+ SquareTextArrowRepeatAll20 = 0xF0811,
+ SquareTextArrowRepeatAll24 = 0xF0812,
+ Translate32 = 0xF0813,
+ Brain20 = 0xF0814,
+ Brain24 = 0xF0815,
+ BrainSparkle20 = 0xF0816,
+ CircleHint28 = 0xF0817,
+ CircleHint32 = 0xF0818,
+ CircleHint48 = 0xF0819,
+ CircleHintCursor16 = 0xF081A,
+ CircleHintCursor20 = 0xF081B,
+ CircleHintCursor24 = 0xF081C,
+ CircleHintDismiss16 = 0xF081D,
+ CircleHintDismiss20 = 0xF081E,
+ CircleHintDismiss24 = 0xF081F,
+ CircleMultipleConcentric16 = 0xF0820,
+ CircleMultipleConcentric20 = 0xF0821,
+ CircleMultipleConcentric24 = 0xF0822,
+ DatabaseCheckmark16 = 0xF0823,
+ DatabaseCheckmark20 = 0xF0824,
+ DatabaseCheckmark24 = 0xF0825,
+ Directions28 = 0xF0826,
+ Directions32 = 0xF0827,
+ Directions48 = 0xF0828,
+ FolderOpen28 = 0xF0829,
+ FolderOpenDown16 = 0xF082A,
+ FolderOpenDown20 = 0xF082B,
+ FolderOpenDown24 = 0xF082C,
+ FolderOpenDown28 = 0xF082D,
+ HdOff16 = 0xF082E,
+ HdOff20 = 0xF082F,
+ HdOff24 = 0xF0830,
+ MailInbox48 = 0xF0831,
+ MailInboxPerson48 = 0xF0832,
+ MailReadBriefcase20 = 0xF0833,
+ MailReadBriefcase24 = 0xF0834,
+ RowChild16 = 0xF0835,
+ RowChild20 = 0xF0836,
+ RowChild24 = 0xF0837,
+ RowChild28 = 0xF0838,
+ RowChild32 = 0xF0839,
+ Bot16 = 0xF083A,
+ Bot28 = 0xF083B,
+ Bot32 = 0xF083C,
+ Bot48 = 0xF083D,
+ BotAdd16 = 0xF083E,
+ BotAdd28 = 0xF083F,
+ BotAdd32 = 0xF0840,
+ BotAdd48 = 0xF0841,
+ BotSparkle16 = 0xF0842,
+ BotSparkle28 = 0xF0843,
+ BotSparkle32 = 0xF0844,
+ BotSparkle48 = 0xF0845,
+ ChatHistory20 = 0xF0846,
+ ChatHistory24 = 0xF0847,
+ ChatHistory28 = 0xF0848,
+ CircleMultipleHintCheckmark20 = 0xF0849,
+ CircleMultipleHintCheckmark24 = 0xF084A,
+ CircleMultipleHintCheckmark28 = 0xF084B,
+ CircleSparkle16 = 0xF084C,
+ CircleSparkle20 = 0xF084D,
+ CircleSparkle24 = 0xF084E,
+ CircleSparkle28 = 0xF084F,
+ CircleSparkle32 = 0xF0850,
+ CircleSparkle48 = 0xF0851,
+ Copy28 = 0xF0852,
+ DocumentSparkle16 = 0xF0853,
+ DocumentSparkle20 = 0xF0854,
+ DocumentSparkle24 = 0xF0855,
+ DocumentSparkle28 = 0xF0856,
+ DocumentSparkle32 = 0xF0857,
+ DocumentSparkle48 = 0xF0858,
+ HomeEmpty20 = 0xF0859,
+ HomeEmpty24 = 0xF085A,
+ HomeEmpty28 = 0xF085B,
+ PaintBucketBrush16 = 0xF085C,
+ PaintBucketBrush20 = 0xF085D,
+ PaintBucketBrush24 = 0xF085E,
+ PaintBucketBrush28 = 0xF085F,
+ ReOrderVertical16 = 0xF0860,
+ ReOrderVertical20 = 0xF0861,
+ ReOrderVertical24 = 0xF0862,
+ Savings32 = 0xF0863,
+ ShareScreenStart16 = 0xF0864,
+ WeatherMoon32 = 0xF0865,
+ LocationCheckmark12 = 0xF0866,
+ LocationCheckmark16 = 0xF0867,
+ LocationCheckmark20 = 0xF0868,
+ LocationCheckmark24 = 0xF0869,
+ LocationCheckmark48 = 0xF086A,
}
+
+#pragma warning restore CS1591
diff --git a/src/Wpf.Ui/Controls/SymbolRegular.cs b/src/Wpf.Ui/Controls/SymbolRegular.cs
index a60740fa4..77650f424 100644
--- a/src/Wpf.Ui/Controls/SymbolRegular.cs
+++ b/src/Wpf.Ui/Controls/SymbolRegular.cs
@@ -6,9 +6,10 @@
namespace Wpf.Ui.Controls;
///
-/// Represents a list of regular Fluent System Icons v.1.1.233.
+/// Represents a list of regular Fluent System Icons v.1.1.271.
/// May be converted to using GetGlyph() or to using GetString()
///
+#pragma warning disable CS1591
public enum SymbolRegular
{
///
@@ -7824,4 +7825,595 @@ public enum SymbolRegular
SpatulaSpoon28 = 0xF0599,
SpatulaSpoon32 = 0xF059A,
SpatulaSpoon48 = 0xF059B,
+ AppsSettings16 = 0xF059C,
+ AppsSettings20 = 0xF059D,
+ AppsShield16 = 0xF059E,
+ AppsShield20 = 0xF059F,
+ ArrowUpload32 = 0xF05A0,
+ CalendarEdit32 = 0xF05A1,
+ DataBarVerticalArrowDown16 = 0xF05A2,
+ DataBarVerticalArrowDown20 = 0xF05A3,
+ DataBarVerticalArrowDown24 = 0xF05A4,
+ HapticStrong16 = 0xF05A5,
+ HapticStrong20 = 0xF05A6,
+ HapticStrong24 = 0xF05A7,
+ HapticWeak16 = 0xF05A8,
+ HapticWeak20 = 0xF05A9,
+ HapticWeak24 = 0xF05AA,
+ HexagonSparkle20 = 0xF05AB,
+ HexagonSparkle24 = 0xF05AC,
+ MailEdit32 = 0xF05AD,
+ Password32 = 0xF05AE,
+ Password48 = 0xF05AF,
+ PasswordClock48 = 0xF05B0,
+ PasswordReset48 = 0xF05B1,
+ PeopleEye16 = 0xF05B2,
+ PeopleEye20 = 0xF05B3,
+ PinGlobe16 = 0xF05B4,
+ PinGlobe20 = 0xF05B5,
+ Run28 = 0xF05B6,
+ Run32 = 0xF05B7,
+ Run48 = 0xF05B8,
+ TabGroup16 = 0xF05B9,
+ TabGroup20 = 0xF05BA,
+ TabGroup24 = 0xF05BB,
+ Book28 = 0xF05BC,
+ Book48 = 0xF05BD,
+ CameraArrowUp16 = 0xF05BE,
+ CameraArrowUp20 = 0xF05BF,
+ CameraArrowUp24 = 0xF05C0,
+ ChatSettings16 = 0xF05C1,
+ CircleHighlight20 = 0xF05C2,
+ CircleHighlight24 = 0xF05C3,
+ CircleHint24 = 0xF05C4,
+ CircleShadow20 = 0xF05C5,
+ CircleShadow24 = 0xF05C6,
+ ContentView16 = 0xF05C7,
+ DoubleTapSwipeDown16 = 0xF05C8,
+ DoubleTapSwipeUp16 = 0xF05C9,
+ FlashSparkle16 = 0xF05CA,
+ LocationRipple12 = 0xF05CB,
+ SearchSquare16 = 0xF05CC,
+ SettingsChat16 = 0xF05CD,
+ ShareMultiple16 = 0xF05CE,
+ ShareMultiple20 = 0xF05CF,
+ ShareMultiple24 = 0xF05D0,
+ SlidePlay20 = 0xF05D1,
+ SlidePlay24 = 0xF05D2,
+ ArrowTurnRight16 = 0xF05D3,
+ ChartMultiple16 = 0xF05D4,
+ Column24 = 0xF05D5,
+ DataPie16 = 0xF05D6,
+ LayoutColumnTwo32 = 0xF05D7,
+ LayoutRowTwo32 = 0xF05D8,
+ MailCopy32 = 0xF05D9,
+ PaintBrushSparkle20 = 0xF05DA,
+ PaintBrushSparkle24 = 0xF05DB,
+ PeopleCommunity12 = 0xF05DC,
+ PersonBoard12 = 0xF05DD,
+ PersonTentative16 = 0xF05DE,
+ PersonTentative20 = 0xF05DF,
+ PersonTentative24 = 0xF05E0,
+ TabDesktopSearch16 = 0xF05E1,
+ TabDesktopSearch20 = 0xF05E2,
+ TabDesktopSearch24 = 0xF05E3,
+ TableSparkle20 = 0xF05E4,
+ TableSparkle24 = 0xF05E5,
+ Comment32 = 0xF05E6,
+ CommentAdd32 = 0xF05E7,
+ CropArrowRotate16 = 0xF05E8,
+ CropArrowRotate20 = 0xF05E9,
+ CropArrowRotate24 = 0xF05EA,
+ DesktopOff20 = 0xF05EB,
+ DesktopOff24 = 0xF05EC,
+ Food28 = 0xF05ED,
+ Food32 = 0xF05EE,
+ Food48 = 0xF05EF,
+ LayerDiagonalAdd24 = 0xF05F0,
+ MailAlert32 = 0xF05F1,
+ MailArrowClockwise32 = 0xF05F2,
+ PersonSupport32 = 0xF05F3,
+ TagOff16 = 0xF05F4,
+ TextColumnOneWideLightning16 = 0xF05F5,
+ WalletCreditCard28 = 0xF05F6,
+ WalletCreditCard48 = 0xF05F7,
+ BreakoutRoom32 = 0xF05F8,
+ CardUiPortraitFlip16 = 0xF05F9,
+ CardUiPortraitFlip20 = 0xF05FA,
+ CardUiPortraitFlip24 = 0xF05FB,
+ Cursor28 = 0xF05FC,
+ Cursor32 = 0xF05FD,
+ LayoutRowTwo28 = 0xF05FE,
+ LayoutRowTwo48 = 0xF05FF,
+ NotepadSparkle16 = 0xF0600,
+ NotepadSparkle20 = 0xF0601,
+ NotepadSparkle24 = 0xF0602,
+ NotepadSparkle28 = 0xF0603,
+ NotepadSparkle32 = 0xF0604,
+ PaintBrush28 = 0xF0605,
+ PaintBrushSubtract16 = 0xF0606,
+ PaintBrushSubtract20 = 0xF0607,
+ PaintBrushSubtract24 = 0xF0608,
+ PaintBrushSubtract28 = 0xF0609,
+ PaintBrushSubtract32 = 0xF060A,
+ PlayCircleSparkle16 = 0xF060B,
+ PlayCircleSparkle20 = 0xF060C,
+ PlayCircleSparkle24 = 0xF060D,
+ Replay16 = 0xF060E,
+ Replay24 = 0xF060F,
+ Replay28 = 0xF0610,
+ Replay32 = 0xF0611,
+ SendPerson16 = 0xF0612,
+ SendPerson20 = 0xF0613,
+ SendPerson24 = 0xF0614,
+ SquareDovetailJoint12 = 0xF0615,
+ SquareDovetailJoint16 = 0xF0616,
+ SquareDovetailJoint20 = 0xF0617,
+ SquareDovetailJoint24 = 0xF0618,
+ SquareDovetailJoint28 = 0xF0619,
+ SquareDovetailJoint32 = 0xF061A,
+ SquareDovetailJoint48 = 0xF061B,
+ TableCursor16 = 0xF061C,
+ TableCursor20 = 0xF061D,
+ TableCursor24 = 0xF061E,
+ TransparencySquare20 = 0xF061F,
+ TransparencySquare24 = 0xF0620,
+ ArrowCollapseAll16 = 0xF0621,
+ ArrowExpandAll16 = 0xF0622,
+ ArrowExpandAll20 = 0xF0623,
+ ArrowExpandAll24 = 0xF0624,
+ ChatArrowBackDown16 = 0xF0625,
+ ChatArrowBackDown20 = 0xF0626,
+ ChatArrowBackDown24 = 0xF0627,
+ ChatArrowBackDown28 = 0xF0628,
+ ChatArrowBackDown32 = 0xF0629,
+ ChatArrowBackDown48 = 0xF062A,
+ DesktopArrowDown32 = 0xF062B,
+ EditLineHorizontal320 = 0xF062C,
+ EditLineHorizontal324 = 0xF062D,
+ GiftOpen32 = 0xF062E,
+ Prompt16 = 0xF062F,
+ Prompt20 = 0xF0630,
+ Prompt24 = 0xF0631,
+ Prompt28 = 0xF0632,
+ Prompt32 = 0xF0633,
+ Prompt48 = 0xF0634,
+ SearchSparkle16 = 0xF0635,
+ SearchSparkle20 = 0xF0636,
+ SearchSparkle24 = 0xF0637,
+ SearchSparkle28 = 0xF0638,
+ SearchSparkle32 = 0xF0639,
+ SearchSparkle48 = 0xF063A,
+ SlideTextCall16 = 0xF063B,
+ SlideTextCall20 = 0xF063C,
+ SlideTextCall24 = 0xF063D,
+ SlideTextCall28 = 0xF063E,
+ SlideTextCall48 = 0xF063F,
+ SlideTextCursor20 = 0xF0640,
+ SlideTextCursor24 = 0xF0641,
+ VehicleMotorcycle16 = 0xF0642,
+ VehicleMotorcycle20 = 0xF0643,
+ VehicleMotorcycle24 = 0xF0644,
+ VehicleMotorcycle28 = 0xF0645,
+ VehicleMotorcycle32 = 0xF0646,
+ VehicleMotorcycle48 = 0xF0647,
+ AccessibilityMore16 = 0xF0648,
+ AccessibilityMore20 = 0xF0649,
+ AccessibilityMore24 = 0xF064A,
+ Battery028 = 0xF064B,
+ Battery032 = 0xF064C,
+ Battery128 = 0xF064D,
+ Battery132 = 0xF064E,
+ Battery1028 = 0xF064F,
+ Battery1032 = 0xF0650,
+ Battery228 = 0xF0651,
+ Battery232 = 0xF0652,
+ Battery328 = 0xF0653,
+ Battery332 = 0xF0654,
+ Battery428 = 0xF0655,
+ Battery432 = 0xF0656,
+ Battery528 = 0xF0657,
+ Battery532 = 0xF0658,
+ Battery628 = 0xF0659,
+ Battery632 = 0xF065A,
+ Battery728 = 0xF065B,
+ Battery732 = 0xF065C,
+ Battery828 = 0xF065D,
+ Battery832 = 0xF065E,
+ Battery928 = 0xF065F,
+ Battery932 = 0xF0660,
+ BatteryCharge28 = 0xF0661,
+ BatteryCharge32 = 0xF0662,
+ CoinStack16 = 0xF0663,
+ CoinStack20 = 0xF0664,
+ CoinStack24 = 0xF0665,
+ DatabaseArrowUp16 = 0xF0666,
+ PaintBrush12 = 0xF0667,
+ PanelRight12 = 0xF0668,
+ PeopleEdit32 = 0xF0669,
+ PersonMail32 = 0xF066A,
+ PuzzlePiece12 = 0xF066B,
+ GameChat20 = 0xF066C,
+ PersonHome16 = 0xF066D,
+ PersonHome20 = 0xF066E,
+ PersonHome24 = 0xF066F,
+ PersonHome28 = 0xF0670,
+ PersonHome32 = 0xF0671,
+ PersonHome48 = 0xF0672,
+ Teaching20 = 0xF0673,
+ EditLock16 = 0xF0674,
+ EditLock20 = 0xF0675,
+ EditLock24 = 0xF0676,
+ LayoutRowTwoSettings20 = 0xF0677,
+ LayoutRowTwoSettings24 = 0xF0678,
+ LayoutRowTwoSettings28 = 0xF0679,
+ LayoutRowTwoSettings32 = 0xF067A,
+ ShieldAdd28 = 0xF0680,
+ ShieldAdd32 = 0xF0681,
+ ShieldAdd48 = 0xF0682,
+ ShieldCheckmark32 = 0xF0683,
+ ShieldTask32 = 0xF0684,
+ Toolbox32 = 0xF0685,
+ WarningLockOpen16 = 0xF0686,
+ WarningLockOpen20 = 0xF0687,
+ WarningLockOpen24 = 0xF0688,
+ PersonBoardAdd20 = 0xF0689,
+ PersonSquareAdd16 = 0xF068A,
+ PersonSquareAdd20 = 0xF068B,
+ PersonSquareAdd24 = 0xF068C,
+ Airplane16 = 0xF068D,
+ Airplane28 = 0xF068E,
+ Airplane32 = 0xF068F,
+ Airplane48 = 0xF0690,
+ GlobeOff12 = 0xF0691,
+ GlobeOff16 = 0xF0692,
+ GlobeOff20 = 0xF0693,
+ GlobeOff24 = 0xF0694,
+ GlobeOff28 = 0xF0695,
+ GlobeOff32 = 0xF0696,
+ GlobeOff48 = 0xF0697,
+ HatGraduation32 = 0xF0698,
+ HatGraduation48 = 0xF0699,
+ PersonBoardAdd16 = 0xF069A,
+ PersonBoardAdd24 = 0xF069B,
+ PersonBoardAdd28 = 0xF069C,
+ PersonBoardAdd32 = 0xF069D,
+ ShoppingBag28 = 0xF069E,
+ ShoppingBag32 = 0xF069F,
+ ShoppingBag48 = 0xF06A0,
+ ShoppingBagTag16 = 0xF06A1,
+ ShoppingBagTag28 = 0xF06A2,
+ ShoppingBagTag32 = 0xF06A3,
+ ShoppingBagTag48 = 0xF06A4,
+ Teaching16 = 0xF06A5,
+ Teaching24 = 0xF06A6,
+ Teaching28 = 0xF06A7,
+ Teaching32 = 0xF06A8,
+ Teaching48 = 0xF06A9,
+ WindowBrush20 = 0xF06AA,
+ WindowBrush24 = 0xF06AB,
+ WindowColumnOneFourthLeft20 = 0xF06AC,
+ ArrowSyncCircle28 = 0xF06AD,
+ ArrowSyncCircle32 = 0xF06AE,
+ ArrowSyncCircle48 = 0xF06AF,
+ CalendarArrowRepeatAll16 = 0xF06B0,
+ CalendarArrowRepeatAll20 = 0xF06B1,
+ CalendarArrowRepeatAll24 = 0xF06B2,
+ CalendarArrowRepeatAll28 = 0xF06B3,
+ CalendarArrowRepeatAll32 = 0xF06B4,
+ CalendarArrowRepeatAll48 = 0xF06B5,
+ CoinMultiple28 = 0xF06B6,
+ CoinMultiple32 = 0xF06B7,
+ CoinMultiple48 = 0xF06B8,
+ BinFull48 = 0xF06B9,
+ ClockToolbox32 = 0xF06BA,
+ DatabaseSearch32 = 0xF06BB,
+ DocumentGlobe20 = 0xF06BC,
+ DocumentGlobe24 = 0xF06BD,
+ FormSparkle20 = 0xF06BE,
+ LineStyleSketch16 = 0xF06BF,
+ LineStyleSketch20 = 0xF06C0,
+ LineStyleSketch24 = 0xF06C1,
+ LineStyleSketch28 = 0xF06C2,
+ LineStyleSketch32 = 0xF06C3,
+ Microscope32 = 0xF06C4,
+ PuzzlePiece28 = 0xF06C5,
+ PuzzlePiece32 = 0xF06C6,
+ PuzzlePiece48 = 0xF06C7,
+ Reward32 = 0xF06C8,
+ TabAdd32 = 0xF06C9,
+ AddCircle48 = 0xF06CA,
+ ApprovalsApp48 = 0xF06CB,
+ ClipboardTextEdit48 = 0xF06CC,
+ DesignIdeas28 = 0xF06CD,
+ DesignIdeas32 = 0xF06CE,
+ DesignIdeas48 = 0xF06CF,
+ DocumentFolder28 = 0xF06D0,
+ DocumentFolder32 = 0xF06D1,
+ DocumentFolder48 = 0xF06D2,
+ EyeOff32 = 0xF06D3,
+ LearningApp16 = 0xF06D4,
+ Receipt48 = 0xF06D5,
+ VideoBluetooth16 = 0xF06D6,
+ VideoBluetooth20 = 0xF06D7,
+ VideoBluetooth24 = 0xF06D8,
+ VideoBluetooth28 = 0xF06D9,
+ VideoBluetooth32 = 0xF06DA,
+ VideoBluetooth48 = 0xF06DB,
+ VideoUsb16 = 0xF06DC,
+ VideoUsb20 = 0xF06DD,
+ VideoUsb24 = 0xF06DE,
+ VideoUsb28 = 0xF06DF,
+ VideoUsb32 = 0xF06E0,
+ VideoUsb48 = 0xF06E1,
+ ArrowCircleUpLeft16 = 0xF06E2,
+ ArrowCircleUpRight16 = 0xF06E3,
+ BuildingCheckmark16 = 0xF06E4,
+ BuildingCheckmark20 = 0xF06E5,
+ ClockAlarm48 = 0xF06E6,
+ ClothesHanger12 = 0xF06E7,
+ ClothesHanger16 = 0xF06E8,
+ ClothesHanger20 = 0xF06E9,
+ ClothesHanger24 = 0xF06EA,
+ CommentQuote16 = 0xF06EB,
+ CommentQuote20 = 0xF06EC,
+ CommentQuote24 = 0xF06ED,
+ CommentQuote28 = 0xF06EE,
+ CommentText16 = 0xF06EF,
+ CommentText20 = 0xF06F0,
+ CommentText24 = 0xF06F1,
+ CommentText28 = 0xF06F2,
+ CommentText32 = 0xF06F3,
+ CommentText48 = 0xF06F4,
+ Glance16 = 0xF06F5,
+ Glance28 = 0xF06F6,
+ Glance32 = 0xF06F7,
+ Glance48 = 0xF06F8,
+ GlanceHorizontal28 = 0xF06F9,
+ GlanceHorizontal48 = 0xF06FA,
+ Megaphone12 = 0xF06FB,
+ MicLink16 = 0xF06FC,
+ MicLink20 = 0xF06FD,
+ MicLink24 = 0xF06FE,
+ MicLink28 = 0xF06FF,
+ MicLink32 = 0xF0700,
+ MicLink48 = 0xF0701,
+ PenSync16 = 0xF0702,
+ PenSync20 = 0xF0703,
+ PenSync24 = 0xF0704,
+ PenSync28 = 0xF0705,
+ PenSync32 = 0xF0706,
+ PenSync48 = 0xF0707,
+ PeopleLink16 = 0xF0708,
+ PeopleLink20 = 0xF0709,
+ PeopleLink24 = 0xF070A,
+ PeopleLink28 = 0xF070B,
+ PeopleLink32 = 0xF070C,
+ PeopleLink48 = 0xF070D,
+ PeopleQueue28 = 0xF070E,
+ PeopleQueue32 = 0xF070F,
+ PeopleQueue48 = 0xF0710,
+ PersonHeadHint16 = 0xF0711,
+ PersonHeadHint20 = 0xF0712,
+ PersonHeadHint24 = 0xF0713,
+ PersonSoundSpatial16 = 0xF0714,
+ PersonSoundSpatial20 = 0xF0715,
+ PersonSoundSpatial24 = 0xF0716,
+ PersonSoundSpatial28 = 0xF0717,
+ PersonSoundSpatial32 = 0xF0718,
+ PersonSoundSpatial48 = 0xF0719,
+ SoundWaveCircle16 = 0xF071A,
+ SoundWaveCircle28 = 0xF071B,
+ SoundWaveCircle32 = 0xF071C,
+ SoundWaveCircle48 = 0xF071D,
+ SoundWaveCircleSparkle16 = 0xF071E,
+ SoundWaveCircleSparkle20 = 0xF071F,
+ SoundWaveCircleSparkle24 = 0xF0720,
+ SoundWaveCircleSparkle28 = 0xF0721,
+ SoundWaveCircleSparkle32 = 0xF0722,
+ SoundWaveCircleSparkle48 = 0xF0723,
+ ArrowDownRight16 = 0xF0724,
+ ArrowDownRight20 = 0xF0725,
+ ArrowDownRight24 = 0xF0726,
+ ArrowDownRight32 = 0xF0727,
+ ArrowDownRight48 = 0xF0728,
+ ArrowRepeatAll28 = 0xF0729,
+ ArrowRepeatAll48 = 0xF072A,
+ Attach28 = 0xF072B,
+ Attach48 = 0xF072C,
+ CalendarMention16 = 0xF072D,
+ CalendarPerson32 = 0xF072E,
+ CommentMultipleMention16 = 0xF072F,
+ CommentMultipleMention20 = 0xF0730,
+ DocumentText28 = 0xF0731,
+ DocumentText32 = 0xF0732,
+ DocumentText48 = 0xF0733,
+ EqualCircle16 = 0xF0734,
+ FolderDocument16 = 0xF0735,
+ FolderDocument20 = 0xF0736,
+ FolderDocument24 = 0xF0737,
+ FolderDocument28 = 0xF0738,
+ MailInbox32 = 0xF0739,
+ MailInboxPerson16 = 0xF073A,
+ MailInboxPerson20 = 0xF073B,
+ MailInboxPerson32 = 0xF073C,
+ PlugConnected28 = 0xF073D,
+ PlugConnected32 = 0xF073E,
+ PlugConnected48 = 0xF073F,
+ ArrowBounce12 = 0xF0740,
+ ArrowBounce28 = 0xF0741,
+ ArrowBounce48 = 0xF0742,
+ ArrowDownLeft12 = 0xF0743,
+ ArrowDownLeft28 = 0xF0744,
+ ArrowFlowDiagonalUpRight12 = 0xF0745,
+ ArrowFlowDiagonalUpRight28 = 0xF0746,
+ ArrowFlowDiagonalUpRight48 = 0xF0747,
+ ArrowUpRight12 = 0xF0748,
+ ArrowUpRight28 = 0xF0749,
+ ArrowUpRightDashes12 = 0xF074A,
+ ArrowUpRightDashes20 = 0xF074B,
+ ArrowUpRightDashes24 = 0xF074C,
+ ArrowUpRightDashes28 = 0xF074D,
+ ArrowUpRightDashes32 = 0xF074E,
+ ArrowUpRightDashes48 = 0xF074F,
+ ArrowWrap32 = 0xF0750,
+ ArrowWrapUpToDown20 = 0xF0751,
+ ArrowWrapUpToDown32 = 0xF0752,
+ CoinMultiple16 = 0xF0753,
+ CoinMultiple20 = 0xF0754,
+ CoinMultiple24 = 0xF0755,
+ CommentBadge16 = 0xF0756,
+ CommentBadge20 = 0xF0757,
+ CommentBadge24 = 0xF0758,
+ DataUsage28 = 0xF0759,
+ DataUsage32 = 0xF075A,
+ DataUsage48 = 0xF075B,
+ DataUsageCheckmark16 = 0xF075C,
+ DataUsageCheckmark20 = 0xF075D,
+ DataUsageCheckmark24 = 0xF075E,
+ DataUsageCheckmark28 = 0xF075F,
+ DataUsageCheckmark32 = 0xF0760,
+ DataUsageCheckmark48 = 0xF0761,
+ LineHorizontal1DashDotDash20 = 0xF0762,
+ LineHorizontal1Dot20 = 0xF0763,
+ LineHorizontal316 = 0xF0764,
+ LineHorizontal324 = 0xF0765,
+ LineHorizontal328 = 0xF0766,
+ LineHorizontal332 = 0xF0767,
+ LineHorizontal348 = 0xF0768,
+ Navigation28 = 0xF0769,
+ Navigation32 = 0xF076A,
+ Navigation48 = 0xF076B,
+ PauseCircle16 = 0xF076C,
+ Stack28 = 0xF076D,
+ Stack48 = 0xF076E,
+ StackOff16 = 0xF076F,
+ StackOff20 = 0xF0770,
+ StackOff24 = 0xF0771,
+ StackOff28 = 0xF0772,
+ StackOff32 = 0xF0773,
+ StackOff48 = 0xF0774,
+ TextBulletListSquare28 = 0xF0775,
+ Textbox28 = 0xF0776,
+ Textbox32 = 0xF0777,
+ Textbox48 = 0xF0778,
+ TextboxCheckmark16 = 0xF0779,
+ TextboxCheckmark20 = 0xF077A,
+ TextboxCheckmark24 = 0xF077B,
+ TextboxCheckmark28 = 0xF077C,
+ TextboxCheckmark32 = 0xF077D,
+ TextboxCheckmark48 = 0xF077E,
+ DocumentOnePageMultipleSparkle16 = 0xF077F,
+ DocumentOnePageMultipleSparkle20 = 0xF0780,
+ DocumentOnePageMultipleSparkle24 = 0xF0781,
+ AnimalPawPrint16 = 0xF0782,
+ AnimalPawPrint20 = 0xF0783,
+ AnimalPawPrint24 = 0xF0784,
+ AnimalPawPrint28 = 0xF0785,
+ AnimalPawPrint32 = 0xF0786,
+ AnimalPawPrint48 = 0xF0787,
+ ArrowClockwiseDashes28 = 0xF0788,
+ ArrowClockwiseDashes48 = 0xF0789,
+ ArrowClockwiseDashesSettings16 = 0xF078A,
+ ArrowClockwiseDashesSettings20 = 0xF078B,
+ ArrowClockwiseDashesSettings24 = 0xF078C,
+ ArrowClockwiseDashesSettings28 = 0xF078D,
+ ArrowClockwiseDashesSettings32 = 0xF078E,
+ ArrowClockwiseDashesSettings48 = 0xF078F,
+ ChatOff16 = 0xF0790,
+ Connected24 = 0xF0791,
+ Connected32 = 0xF0792,
+ SquareTextArrowRepeatAll16 = 0xF0793,
+ SquareTextArrowRepeatAll20 = 0xF0794,
+ SquareTextArrowRepeatAll24 = 0xF0795,
+ Translate32 = 0xF0796,
+ Brain20 = 0xF0797,
+ Brain24 = 0xF0798,
+ BrainSparkle20 = 0xF0799,
+ CircleHint28 = 0xF079A,
+ CircleHint32 = 0xF079B,
+ CircleHint48 = 0xF079C,
+ CircleHintCursor16 = 0xF079D,
+ CircleHintCursor20 = 0xF079E,
+ CircleHintCursor24 = 0xF079F,
+ CircleHintDismiss16 = 0xF07A0,
+ CircleHintDismiss20 = 0xF07A1,
+ CircleHintDismiss24 = 0xF07A2,
+ CircleMultipleConcentric16 = 0xF07A3,
+ CircleMultipleConcentric20 = 0xF07A4,
+ CircleMultipleConcentric24 = 0xF07A5,
+ DatabaseCheckmark16 = 0xF07A6,
+ DatabaseCheckmark20 = 0xF07A7,
+ DatabaseCheckmark24 = 0xF07A8,
+ Directions28 = 0xF07A9,
+ Directions32 = 0xF07AA,
+ Directions48 = 0xF07AB,
+ FolderOpen28 = 0xF07AC,
+ FolderOpenDown16 = 0xF07AD,
+ FolderOpenDown20 = 0xF07AE,
+ FolderOpenDown24 = 0xF07AF,
+ FolderOpenDown28 = 0xF07B0,
+ HdOff16 = 0xF07B1,
+ HdOff20 = 0xF07B2,
+ HdOff24 = 0xF07B3,
+ MailInbox48 = 0xF07B4,
+ MailInboxPerson48 = 0xF07B5,
+ MailReadBriefcase20 = 0xF07B6,
+ MailReadBriefcase24 = 0xF07B7,
+ RowChild16 = 0xF07B8,
+ RowChild20 = 0xF07B9,
+ RowChild24 = 0xF07BA,
+ RowChild28 = 0xF07BB,
+ RowChild32 = 0xF07BC,
+ Bot16 = 0xF07BD,
+ Bot28 = 0xF07BE,
+ Bot32 = 0xF07BF,
+ Bot48 = 0xF07C0,
+ BotAdd16 = 0xF07C1,
+ BotAdd28 = 0xF07C2,
+ BotAdd32 = 0xF07C3,
+ BotAdd48 = 0xF07C4,
+ BotSparkle16 = 0xF07C5,
+ BotSparkle28 = 0xF07C6,
+ BotSparkle32 = 0xF07C7,
+ BotSparkle48 = 0xF07C8,
+ ChatHistory20 = 0xF07C9,
+ ChatHistory24 = 0xF07CA,
+ ChatHistory28 = 0xF07CB,
+ CircleMultipleHintCheckmark20 = 0xF07CC,
+ CircleMultipleHintCheckmark24 = 0xF07CD,
+ CircleMultipleHintCheckmark28 = 0xF07CE,
+ CircleSparkle16 = 0xF07CF,
+ CircleSparkle20 = 0xF07D0,
+ CircleSparkle24 = 0xF07D1,
+ CircleSparkle28 = 0xF07D2,
+ CircleSparkle32 = 0xF07D3,
+ CircleSparkle48 = 0xF07D4,
+ Copy28 = 0xF07D5,
+ DocumentSparkle16 = 0xF07D6,
+ DocumentSparkle20 = 0xF07D7,
+ DocumentSparkle24 = 0xF07D8,
+ DocumentSparkle28 = 0xF07D9,
+ DocumentSparkle32 = 0xF07DA,
+ DocumentSparkle48 = 0xF07DB,
+ HomeEmpty20 = 0xF07DC,
+ HomeEmpty24 = 0xF07DD,
+ HomeEmpty28 = 0xF07DE,
+ PaintBucketBrush16 = 0xF07DF,
+ PaintBucketBrush20 = 0xF07E0,
+ PaintBucketBrush24 = 0xF07E1,
+ PaintBucketBrush28 = 0xF07E2,
+ ReOrderVertical16 = 0xF07E3,
+ ReOrderVertical20 = 0xF07E4,
+ ReOrderVertical24 = 0xF07E5,
+ Savings32 = 0xF07E6,
+ ShareScreenStart16 = 0xF07E7,
+ WeatherMoon32 = 0xF07E8,
+ LocationCheckmark12 = 0xF07E9,
+ LocationCheckmark16 = 0xF07EA,
+ LocationCheckmark20 = 0xF07EB,
+ LocationCheckmark24 = 0xF07EC,
+ LocationCheckmark48 = 0xF07ED,
}
+
+#pragma warning restore CS1591
diff --git a/src/Wpf.Ui/Controls/TabControl/TabControl.xaml b/src/Wpf.Ui/Controls/TabControl/TabControl.xaml
index 4d18232f2..8c2449aba 100644
--- a/src/Wpf.Ui/Controls/TabControl/TabControl.xaml
+++ b/src/Wpf.Ui/Controls/TabControl/TabControl.xaml
@@ -76,7 +76,6 @@
/// Gets or sets the of the text.
///
diff --git a/src/Wpf.Ui/Controls/TextBox/TextBox.cs b/src/Wpf.Ui/Controls/TextBox/TextBox.cs
index 25b2f8ffc..b0023872d 100644
--- a/src/Wpf.Ui/Controls/TextBox/TextBox.cs
+++ b/src/Wpf.Ui/Controls/TextBox/TextBox.cs
@@ -5,7 +5,6 @@
using System.Diagnostics;
using System.Windows.Controls;
-using Wpf.Ui.Converters;
using Wpf.Ui.Input;
// ReSharper disable once CheckNamespace
diff --git a/src/Wpf.Ui/Controls/TextBox/TextBox.xaml b/src/Wpf.Ui/Controls/TextBox/TextBox.xaml
index 4fc1e5940..e784d22e5 100644
--- a/src/Wpf.Ui/Controls/TextBox/TextBox.xaml
+++ b/src/Wpf.Ui/Controls/TextBox/TextBox.xaml
@@ -56,7 +56,9 @@
+ IsTabStop="False"
+ MouseOverBackground="{DynamicResource SubtleFillColorSecondaryBrush}"
+ MouseOverBorderBrush="Transparent"
+ PressedBackground="{DynamicResource SubtleFillColorTertiaryBrush}"
+ PressedBorderBrush="Transparent">
@@ -249,6 +258,7 @@
+
@@ -278,6 +288,8 @@
x:Name="ContentBorder"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
+ Width="{TemplateBinding Width}"
+ Height="{TemplateBinding Height}"
Padding="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
diff --git a/src/Wpf.Ui/Controls/TextColor.cs b/src/Wpf.Ui/Controls/TextColor.cs
index b235854a4..6acedf720 100644
--- a/src/Wpf.Ui/Controls/TextColor.cs
+++ b/src/Wpf.Ui/Controls/TextColor.cs
@@ -28,5 +28,5 @@ public enum TextColor
///
/// Disabled only (not accessible)
///
- Disabled
+ Disabled,
}
diff --git a/src/Wpf.Ui/Controls/ThumbRate/ThumbRateState.cs b/src/Wpf.Ui/Controls/ThumbRate/ThumbRateState.cs
index c4d570640..d2c4e1c10 100644
--- a/src/Wpf.Ui/Controls/ThumbRate/ThumbRateState.cs
+++ b/src/Wpf.Ui/Controls/ThumbRate/ThumbRateState.cs
@@ -24,5 +24,5 @@ public enum ThumbRateState
///
/// The thumb down has been clicked.
///
- Disliked
+ Disliked,
}
diff --git a/src/Wpf.Ui/Controls/TimePicker/ClockIdentifier.cs b/src/Wpf.Ui/Controls/TimePicker/ClockIdentifier.cs
index 7e154f2f5..9f20df28d 100644
--- a/src/Wpf.Ui/Controls/TimePicker/ClockIdentifier.cs
+++ b/src/Wpf.Ui/Controls/TimePicker/ClockIdentifier.cs
@@ -12,5 +12,5 @@ namespace Wpf.Ui.Controls;
public enum ClockIdentifier
{
Clock12Hour,
- Clock24Hour
+ Clock24Hour,
}
diff --git a/src/Wpf.Ui/Controls/TitleBar/HwndProcEventArgs.cs b/src/Wpf.Ui/Controls/TitleBar/HwndProcEventArgs.cs
new file mode 100644
index 000000000..79b7c948c
--- /dev/null
+++ b/src/Wpf.Ui/Controls/TitleBar/HwndProcEventArgs.cs
@@ -0,0 +1,39 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+// ReSharper disable once CheckNamespace
+namespace Wpf.Ui.Controls;
+
+public class HwndProcEventArgs : EventArgs
+{
+ public bool Handled { get; set; }
+
+ public IntPtr? ReturnValue { get; set; }
+
+ public bool IsMouseOverDetectedHeaderContent { get; }
+
+ public IntPtr HWND { get; }
+
+ public int Message { get; }
+
+ public IntPtr WParam { get; }
+
+ public IntPtr LParam { get; }
+
+ internal HwndProcEventArgs(
+ IntPtr hwnd,
+ int msg,
+ IntPtr wParam,
+ IntPtr lParam,
+ bool isMouseOverDetectedHeaderContent
+ )
+ {
+ HWND = hwnd;
+ Message = msg;
+ WParam = wParam;
+ LParam = lParam;
+ IsMouseOverDetectedHeaderContent = isMouseOverDetectedHeaderContent;
+ }
+}
diff --git a/src/Wpf.Ui/Controls/TitleBar/TitleBar.WindowResize.cs b/src/Wpf.Ui/Controls/TitleBar/TitleBar.WindowResize.cs
new file mode 100644
index 000000000..bb6b19a49
--- /dev/null
+++ b/src/Wpf.Ui/Controls/TitleBar/TitleBar.WindowResize.cs
@@ -0,0 +1,283 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Windows.Shell;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.WindowsAndMessaging;
+using RECT = Windows.Win32.Foundation.RECT;
+
+// ReSharper disable once CheckNamespace
+namespace Wpf.Ui.Controls;
+
+///
+/// Provides optional window-resize related hit-testing support for the control.
+///
+///
+/// This partial class implements logic to return appropriate WM_NCHITTEST results (for example
+/// HTLEFT, HTBOTTOMRIGHT, etc.) when the mouse is positioned over the window edges
+/// or corners. This enables intuitive resizing behavior when the user drags the window borders.
+///
+/// Key points:
+/// - The implementation prefers the
+/// value (expressed in device-independent units) when available and translates it into physical pixels;
+/// - If WindowChrome or DPI information is not available, the code falls back to system metrics via
+/// ;
+/// - Because WM_NCHITTEST is raised frequently, computed border pixel sizes are cached to
+/// reduce overhead; the cache is invalidated when DPI or relevant system parameters change;
+/// - This component only augments the control's non-client hit-testing to
+/// improve resize behavior and does not alter the window style or system behavior itself.
+///
+/// Splitting this functionality into a partial class keeps the resize-related responsibilities
+/// clearly separated from other TitleBar UI and interaction logic.
+///
+public partial class TitleBar
+{
+ private int _borderX;
+ private int _borderY;
+
+ private bool _borderXCached;
+ private bool _borderYCached;
+
+ private bool _systemParamsSubscribed;
+
+ private IntPtr GetWindowBorderHitTestResult(IntPtr hwnd, IntPtr lParam)
+ {
+ if (!PInvoke.GetWindowRect(new HWND(hwnd), out RECT windowRect))
+ {
+ return (IntPtr)PInvoke.HTNOWHERE;
+ }
+
+ if (!_borderXCached || !_borderYCached)
+ {
+ ComputeAndCacheBorderSizes(hwnd);
+ }
+
+ long lp = lParam.ToInt64();
+
+ int x = (short)(lp & 0xFFFF);
+ int y = (short)((lp >> 16) & 0xFFFF);
+
+ uint hit = 0u;
+
+#pragma warning disable
+ if (x < windowRect.left + _borderX)
+ hit |= 0b0001u; // left
+ if (x >= windowRect.right - _borderX)
+ hit |= 0b0010u; // right
+ if (y < windowRect.top + _borderY)
+ hit |= 0b0100u; // top
+ if (y >= windowRect.bottom - _borderY)
+ hit |= 0b1000u; // bottom
+#pragma warning restore
+
+ return hit switch
+ {
+ 0b0101u => (IntPtr)PInvoke.HTTOPLEFT, // top + left (0b0100 | 0b0001)
+ 0b0110u => (IntPtr)PInvoke.HTTOPRIGHT, // top + right (0b0100 | 0b0010)
+ 0b1001u => (IntPtr)PInvoke.HTBOTTOMLEFT, // bottom + left (0b1000 | 0b0001)
+ 0b1010u => (IntPtr)PInvoke.HTBOTTOMRIGHT, // bottom + right (0b1000 | 0b0010)
+ 0b0100u => (IntPtr)PInvoke.HTTOP, // top
+ 0b0001u => (IntPtr)PInvoke.HTLEFT, // left
+ 0b1000u => (IntPtr)PInvoke.HTBOTTOM, // bottom
+ 0b0010u => (IntPtr)PInvoke.HTRIGHT, // right
+
+ // no match = HTNOWHERE (stop processing)
+ _ => (IntPtr)PInvoke.HTNOWHERE,
+ };
+ }
+
+ private void SubscribeToSystemParameters()
+ {
+ if (_systemParamsSubscribed)
+ {
+ return;
+ }
+
+ SystemParameters.StaticPropertyChanged += OnSystemParametersChanged;
+ _systemParamsSubscribed = true;
+ }
+
+ private void UnsubscribeToSystemParameters()
+ {
+ if (!_systemParamsSubscribed)
+ {
+ return;
+ }
+
+ SystemParameters.StaticPropertyChanged -= OnSystemParametersChanged;
+ _systemParamsSubscribed = false;
+ }
+
+ private void OnSystemParametersChanged(object? sender, PropertyChangedEventArgs e)
+ {
+ InvalidateBorderCache();
+ }
+
+ private void InvalidateBorderCache()
+ {
+ _borderXCached = false;
+ _borderYCached = false;
+ }
+
+ private void ComputeAndCacheBorderSizes(IntPtr hwnd)
+ {
+ try
+ {
+ double dipBorderX;
+ double dipBorderY;
+
+ Window? win = null;
+ try
+ {
+ var src = HwndSource.FromHwnd(hwnd);
+ if (src?.RootVisual is DependencyObject dep)
+ {
+ win = Window.GetWindow(dep);
+ }
+ }
+ catch
+ {
+ // ignored
+ }
+
+ // FluentWindow uses WindowChrome - get border from it first
+ WindowChrome? chrome = win is null ? null : WindowChrome.GetWindowChrome(win);
+
+ if (chrome is not null)
+ {
+ dipBorderX = Math.Max(chrome.ResizeBorderThickness.Left, chrome.ResizeBorderThickness.Right);
+ dipBorderY = Math.Max(chrome.ResizeBorderThickness.Top, chrome.ResizeBorderThickness.Bottom);
+ }
+ else
+ {
+ dipBorderX = SystemParameters.WindowResizeBorderThickness.Left;
+ dipBorderY = SystemParameters.WindowResizeBorderThickness.Top;
+ }
+
+ int borderX;
+ int borderY;
+
+ if (
+ TryComputeFromPresentationSource(win, dipBorderX, dipBorderY, out borderX, out borderY)
+ || TryComputeFromDpiApi(hwnd, dipBorderX, dipBorderY, out borderX, out borderY)
+ || TryGetFromSystemMetrics(out borderX, out borderY)
+ )
+ {
+ _borderX = borderX;
+ _borderY = borderY;
+ }
+ else
+ {
+ _borderX = 4;
+ _borderY = 4;
+ }
+ }
+ catch
+ {
+ _borderX = 4;
+ _borderY = 4;
+ }
+
+ _borderXCached = true;
+ _borderYCached = true;
+ }
+
+ // Try to compute border sizes from PresentationSource (per-monitor DPI-aware path).
+ private static bool TryComputeFromPresentationSource(
+ Window? win,
+ double dipBorderX,
+ double dipBorderY,
+ out int borderX,
+ out int borderY
+ )
+ {
+ if (win is not null)
+ {
+ try
+ {
+ PresentationSource? source = PresentationSource.FromVisual(win);
+
+ if (source?.CompositionTarget is not null)
+ {
+ Matrix m = source.CompositionTarget.TransformToDevice;
+
+ borderX = Math.Max(2, (int)Math.Ceiling(dipBorderX * m.M11));
+ borderY = Math.Max(2, (int)Math.Ceiling(dipBorderY * m.M22));
+
+ return true;
+ }
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ borderX = 0;
+ borderY = 0;
+
+ return false;
+ }
+
+ // Try to compute border sizes using GetDpiForWindow (if available).
+ private static bool TryComputeFromDpiApi(
+ IntPtr hwnd,
+ double dipBorderX,
+ double dipBorderY,
+ out int borderX,
+ out int borderY
+ )
+ {
+ try
+ {
+ uint dpi = PInvoke.GetDpiForWindow(new HWND(hwnd));
+ if (dpi == 0)
+ {
+ dpi = 96;
+ }
+
+ double scale = dpi / 96.0;
+
+ borderX = Math.Max(2, (int)Math.Ceiling(dipBorderX * scale));
+ borderY = Math.Max(2, (int)Math.Ceiling(dipBorderY * scale));
+
+ return true;
+ }
+ catch
+ {
+ borderX = 0;
+ borderY = 0;
+
+ return false;
+ }
+ }
+
+ // Try to compute border sizes using GetSystemMetrics as a safe fallback.
+ private static bool TryGetFromSystemMetrics(out int borderX, out int borderY)
+ {
+ try
+ {
+ int sx =
+ PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSIZEFRAME)
+ + PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXPADDEDBORDER);
+ int sy =
+ PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSIZEFRAME)
+ + PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXPADDEDBORDER);
+
+ borderX = Math.Max(2, sx);
+ borderY = Math.Max(2, sy);
+
+ return true;
+ }
+ catch
+ {
+ borderX = 0;
+ borderY = 0;
+
+ return false;
+ }
+ }
+}
diff --git a/src/Wpf.Ui/Controls/TitleBar/TitleBar.cs b/src/Wpf.Ui/Controls/TitleBar/TitleBar.cs
index 7dbc9a0f7..67c2d7478 100644
--- a/src/Wpf.Ui/Controls/TitleBar/TitleBar.cs
+++ b/src/Wpf.Ui/Controls/TitleBar/TitleBar.cs
@@ -4,9 +4,10 @@
// All Rights Reserved.
using System.Diagnostics;
+using System.Windows.Data;
using System.Windows.Input;
+using Windows.Win32;
using Wpf.Ui.Designer;
-using Wpf.Ui.Extensions;
using Wpf.Ui.Input;
using Wpf.Ui.Interop;
@@ -23,7 +24,7 @@ namespace Wpf.Ui.Controls;
[TemplatePart(Name = ElementMaximizeButton, Type = typeof(TitleBarButton))]
[TemplatePart(Name = ElementRestoreButton, Type = typeof(TitleBarButton))]
[TemplatePart(Name = ElementCloseButton, Type = typeof(TitleBarButton))]
-public class TitleBar : System.Windows.Controls.Control, IThemeControl
+public partial class TitleBar : System.Windows.Controls.Control, IThemeControl
{
private const string ElementIcon = "PART_Icon";
private const string ElementMainGrid = "PART_MainGrid";
@@ -37,6 +38,8 @@ public class TitleBar : System.Windows.Controls.Control, IThemeControl
private DependencyObject? _parentWindow;
+ public event EventHandler? WndProcInvoked;
+
/// Identifies the dependency property.
public static readonly DependencyProperty ApplicationThemeProperty = DependencyProperty.Register(
nameof(ApplicationTheme),
@@ -53,7 +56,9 @@ public class TitleBar : System.Windows.Controls.Control, IThemeControl
new PropertyMetadata(null)
);
- /// Identifies the dependency property.
+ ///
+ /// Property for .
+ ///
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
nameof(Header),
typeof(object),
@@ -61,6 +66,16 @@ public class TitleBar : System.Windows.Controls.Control, IThemeControl
new PropertyMetadata(null)
);
+ ///
+ /// Property for .
+ ///
+ public static readonly DependencyProperty TrailingContentProperty = DependencyProperty.Register(
+ nameof(TrailingContent),
+ typeof(object),
+ typeof(TitleBar),
+ new PropertyMetadata(null)
+ );
+
/// Identifies the dependency property.
public static readonly DependencyProperty ButtonsForegroundProperty = DependencyProperty.Register(
nameof(ButtonsForeground),
@@ -210,7 +225,7 @@ public string? Title
}
///
- /// Gets or sets the content displayed in the .
+ /// Gets or sets the content displayed in the left side of the .
///
public object? Header
{
@@ -218,6 +233,15 @@ public object? Header
set => SetValue(HeaderProperty, value);
}
+ ///
+ /// Gets or sets the content displayed in right side of the .
+ ///
+ public object? TrailingContent
+ {
+ get => GetValue(TrailingContentProperty);
+ set => SetValue(TrailingContentProperty, value);
+ }
+
///
/// Gets or sets the foreground of the navigation buttons.
///
@@ -373,6 +397,7 @@ public event TypedEventHandler HelpClicked
public Action? MinimizeActionOverride { get; set; }
private readonly TitleBarButton[] _buttons = new TitleBarButton[4];
+ private readonly TextBlock _titleBlock;
private System.Windows.Window _currentWindow = null!;
/*private System.Windows.Controls.Grid _mainGrid = null!;*/
@@ -387,6 +412,22 @@ public TitleBar()
dpiScale ??= VisualTreeHelper.GetDpi(this);
+ _titleBlock = new TextBlock();
+ _titleBlock.VerticalAlignment = VerticalAlignment.Center;
+ _ = _titleBlock.SetBinding(
+ System.Windows.Controls.TextBlock.TextProperty,
+ new Binding(nameof(Title)) { Source = this }
+ );
+ _ = _titleBlock.SetBinding(
+ System.Windows.Controls.TextBlock.FontSizeProperty,
+ new Binding(nameof(FontSize)) { Source = this }
+ );
+ _ = _titleBlock.SetBinding(
+ System.Windows.Controls.TextBlock.FontWeightProperty,
+ new Binding(nameof(FontWeight)) { Source = this }
+ );
+ Header = _titleBlock;
+
Loaded += OnLoaded;
Unloaded += OnUnloaded;
}
@@ -409,8 +450,16 @@ protected virtual void OnLoaded(object sender, RoutedEventArgs e)
_currentWindow =
System.Windows.Window.GetWindow(this) ?? throw new InvalidOperationException("Window is null");
+ if (_currentWindow.WindowState == WindowState.Maximized)
+ {
+ SetCurrentValue(IsMaximizedProperty, true);
+ _currentWindow.SetCurrentValue(Window.WindowStateProperty, WindowState.Maximized);
+ }
+
_currentWindow.StateChanged += OnParentWindowStateChanged;
_currentWindow.ContentRendered += OnWindowContentRendered;
+
+ SubscribeToSystemParameters();
}
private void OnUnloaded(object sender, RoutedEventArgs e)
@@ -419,6 +468,7 @@ private void OnUnloaded(object sender, RoutedEventArgs e)
Unloaded -= OnUnloaded;
Appearance.ApplicationThemeManager.Changed -= OnThemeChanged;
+ UnsubscribeToSystemParameters();
}
///
@@ -534,8 +584,7 @@ private void OnTemplateButtonClick(TitleBarButtonType buttonType)
{
switch (buttonType)
{
- case TitleBarButtonType.Maximize
- or TitleBarButtonType.Restore:
+ case TitleBarButtonType.Maximize or TitleBarButtonType.Restore:
RaiseEvent(new RoutedEventArgs(MaximizeClickedEvent, this));
MaximizeWindow();
break;
@@ -557,7 +606,7 @@ private void OnTemplateButtonClick(TitleBarButtonType buttonType)
}
///
- /// Listening window hooks after rendering window content to SizeToContent support
+ /// Listening window hooks after rendering window content to SizeToContent support
///
private void OnWindowContentRendered(object? sender, EventArgs e)
{
@@ -569,22 +618,37 @@ private void OnWindowContentRendered(object? sender, EventArgs e)
window.ContentRendered -= OnWindowContentRendered;
IntPtr handle = new WindowInteropHelper(window).Handle;
- HwndSource windowSource =
- HwndSource.FromHwnd(handle) ?? throw new InvalidOperationException("Window source is null");
+ if (handle == IntPtr.Zero)
+ {
+ return;
+ }
+
+ HwndSource? windowSource = HwndSource.FromHwnd(handle);
+ if (windowSource == null)
+ {
+ return;
+ }
+
windowSource.AddHook(HwndSourceHook);
}
private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
- var message = (User32.WM)msg;
+ var message = (uint)msg;
+
+ // Invalidate cached border size on DPI change message
+ if (message == PInvoke.WM_DPICHANGED)
+ {
+ InvalidateBorderCache();
+ }
if (
message
is not (
- User32.WM.NCHITTEST
- or User32.WM.NCMOUSELEAVE
- or User32.WM.NCLBUTTONDOWN
- or User32.WM.NCLBUTTONUP
+ PInvoke.WM_NCHITTEST
+ or PInvoke.WM_NCMOUSELEAVE
+ or PInvoke.WM_NCLBUTTONDOWN
+ or PInvoke.WM_NCLBUTTONUP
)
)
{
@@ -617,21 +681,50 @@ or User32.WM.NCLBUTTONUP
}
bool isMouseOverHeaderContent = false;
+ IntPtr htResult = (IntPtr)PInvoke.HTNOWHERE;
+
+ if (message == PInvoke.WM_NCHITTEST)
+ {
+ if (TrailingContent is UIElement || Header is UIElement)
+ {
+ UIElement? headerRightUiElement = TrailingContent as UIElement;
+
+ if (Header is UIElement headerLeftUIElement && headerLeftUIElement != _titleBlock)
+ {
+ isMouseOverHeaderContent =
+ headerLeftUIElement.IsMouseOverElement(lParam)
+ || (headerRightUiElement?.IsMouseOverElement(lParam) ?? false);
+ }
+ else
+ {
+ isMouseOverHeaderContent = headerRightUiElement?.IsMouseOverElement(lParam) ?? false;
+ }
+ }
+
+ htResult = GetWindowBorderHitTestResult(hwnd, lParam);
+ }
+
+ var e = new HwndProcEventArgs(hwnd, msg, wParam, lParam, isMouseOverHeaderContent);
+ WndProcInvoked?.Invoke(this, e);
- if (message == User32.WM.NCHITTEST && Header is UIElement headerUiElement)
+ if (e.ReturnValue != null)
{
- isMouseOverHeaderContent = headerUiElement.IsMouseOverElement(lParam);
+ handled = e.Handled;
+ return e.ReturnValue ?? IntPtr.Zero;
}
switch (message)
{
- case User32.WM.NCHITTEST when CloseWindowByDoubleClickOnIcon && _icon.IsMouseOverElement(lParam):
+ case PInvoke.WM_NCHITTEST when CloseWindowByDoubleClickOnIcon && _icon.IsMouseOverElement(lParam):
// Ideally, clicking on the icon should open the system menu, but when the system menu is opened manually, double-clicking on the icon does not close the window
handled = true;
- return (IntPtr)User32.WM_NCHITTEST.HTSYSMENU;
- case User32.WM.NCHITTEST when this.IsMouseOverElement(lParam) && !isMouseOverHeaderContent:
+ return (IntPtr)PInvoke.HTSYSMENU;
+ case PInvoke.WM_NCHITTEST when htResult != (IntPtr)PInvoke.HTNOWHERE:
+ handled = true;
+ return htResult;
+ case PInvoke.WM_NCHITTEST when this.IsMouseOverElement(lParam) && !isMouseOverHeaderContent:
handled = true;
- return (IntPtr)User32.WM_NCHITTEST.HTCAPTION;
+ return (IntPtr)PInvoke.HTCAPTION;
default:
return IntPtr.Zero;
}
diff --git a/src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml b/src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml
index 82097c1e9..831097e3a 100644
--- a/src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml
+++ b/src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml
@@ -118,7 +118,6 @@
VerticalAlignment="Center">
-
@@ -126,34 +125,35 @@
x:Name="PART_Icon"
Grid.Column="0"
Height="16"
- Margin="0,0,12,0"
VerticalAlignment="Center"
+ AutomationProperties.AutomationId="TitleBarIcon"
Content="{TemplateBinding Icon}"
Focusable="False"
RenderOptions.BitmapScalingMode="HighQuality" />
-
-
-
+
+
-
+
+
+
+
@@ -167,22 +167,26 @@
+ AutomationProperties.AutomationId="TitleBarMaximizeButton"
+ ButtonType="Maximize"
+ IsHitTestVisible="True" />
diff --git a/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs b/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs
index e87f3352f..56bfca17c 100644
--- a/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs
+++ b/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs
@@ -5,8 +5,7 @@
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
-using Wpf.Ui.Extensions;
-using Wpf.Ui.Interop;
+using Windows.Win32;
// ReSharper disable once CheckNamespace
namespace Wpf.Ui.Controls;
@@ -88,7 +87,7 @@ public Brush RenderButtonsForeground
public bool IsHovered { get; private set; }
private readonly Brush _defaultBackgroundBrush = Brushes.Transparent; // REVIEW: Should it be transparent?
- private User32.WM_NCHITTEST _returnValue;
+ private uint _returnValue;
private bool _isClickedDown;
@@ -173,13 +172,13 @@ is IInvokeProvider invokeProvider
_isClickedDown = false;
}
- internal bool ReactToHwndHook(User32.WM msg, IntPtr lParam, out IntPtr returnIntPtr)
+ internal bool ReactToHwndHook(uint msg, IntPtr lParam, out IntPtr returnIntPtr)
{
returnIntPtr = IntPtr.Zero;
switch (msg)
{
- case User32.WM.NCHITTEST:
+ case PInvoke.WM_NCHITTEST:
if (this.IsMouseOverElement(lParam))
{
/*Debug.WriteLine($"Hitting {ButtonType} | return code {_returnValue}");*/
@@ -190,13 +189,13 @@ internal bool ReactToHwndHook(User32.WM msg, IntPtr lParam, out IntPtr returnInt
RemoveHover();
return false;
- case User32.WM.NCMOUSELEAVE: // Mouse leaves the window
+ case PInvoke.WM_NCMOUSELEAVE: // Mouse leaves the window
RemoveHover();
return false;
- case User32.WM.NCLBUTTONDOWN when this.IsMouseOverElement(lParam): // Left button clicked down
+ case PInvoke.WM_NCLBUTTONDOWN when this.IsMouseOverElement(lParam): // Left button clicked down
_isClickedDown = true;
return true;
- case User32.WM.NCLBUTTONUP when _isClickedDown && this.IsMouseOverElement(lParam): // Left button clicked up
+ case PInvoke.WM_NCLBUTTONUP when _isClickedDown && this.IsMouseOverElement(lParam): // Left button clicked up
InvokeClick();
return true;
default:
@@ -220,18 +219,47 @@ protected void OnButtonTypeChanged(DependencyPropertyChangedEventArgs e)
_returnValue = buttonType switch
{
- TitleBarButtonType.Unknown => User32.WM_NCHITTEST.HTNOWHERE,
- TitleBarButtonType.Help => User32.WM_NCHITTEST.HTHELP,
- TitleBarButtonType.Minimize => User32.WM_NCHITTEST.HTMINBUTTON,
- TitleBarButtonType.Close => User32.WM_NCHITTEST.HTCLOSE,
- TitleBarButtonType.Restore => User32.WM_NCHITTEST.HTMAXBUTTON,
- TitleBarButtonType.Maximize => User32.WM_NCHITTEST.HTMAXBUTTON,
- _
- => throw new ArgumentOutOfRangeException(
- "e.NewValue",
- buttonType,
- $"Unsupported button type: {buttonType}."
- )
+ TitleBarButtonType.Unknown => PInvoke.HTNOWHERE,
+ TitleBarButtonType.Help => PInvoke.HTHELP,
+ TitleBarButtonType.Minimize => PInvoke.HTMINBUTTON,
+ TitleBarButtonType.Close => PInvoke.HTCLOSE,
+ TitleBarButtonType.Restore => PInvoke.HTMAXBUTTON,
+ TitleBarButtonType.Maximize => PInvoke.HTMAXBUTTON,
+ _ => throw new ArgumentOutOfRangeException(
+ "e.NewValue",
+ buttonType,
+ $"Unsupported button type: {buttonType}."
+ ),
};
}
+
+ // TODO: Incorrectly calculates mouse position for high DPI displays.
+ // PresentationSource presentationSource = null;
+ // protected bool IsMouseOverElement(nint lParam)
+ // {
+ // System.Drawing.Point winPoint;
+ // bool gotCursorPos = User32.GetCursorPos(out winPoint);
+
+ // if (!gotCursorPos)
+ // {
+ // int fallbackX = unchecked((short)((long)lParam & 0xFFFF));
+ // int fallbackY = unchecked((short)(((long)lParam >> 16) & 0xFFFF));
+ // winPoint = new System.Drawing.Point(fallbackX, fallbackY);
+ // }
+
+ // var screenPoint = new System.Windows.Point(winPoint.X, winPoint.Y);
+
+ // presentationSource ??= PresentationSource.FromVisual(this);
+
+ // if (presentationSource?.CompositionTarget != null)
+ // {
+ // screenPoint = presentationSource.CompositionTarget.TransformFromDevice.Transform(screenPoint);
+ // }
+
+ // var localPoint = this.PointFromScreen(screenPoint);
+
+ // var hitTestRect = new System.Windows.Rect(0, 0, this.ActualWidth, this.ActualHeight);
+
+ // return hitTestRect.Contains(localPoint);
+ //}
}
diff --git a/src/Wpf.Ui/Controls/TitleBar/TitleBarButtonType.cs b/src/Wpf.Ui/Controls/TitleBar/TitleBarButtonType.cs
index da560e0d6..2b363cedb 100644
--- a/src/Wpf.Ui/Controls/TitleBar/TitleBarButtonType.cs
+++ b/src/Wpf.Ui/Controls/TitleBar/TitleBarButtonType.cs
@@ -39,5 +39,5 @@ public enum TitleBarButtonType
///
/// Help button.
///
- Help
+ Help,
}
diff --git a/src/Wpf.Ui/Controls/ToggleButton/ToggleButton.xaml b/src/Wpf.Ui/Controls/ToggleButton/ToggleButton.xaml
index 04af06574..b58d357f0 100644
--- a/src/Wpf.Ui/Controls/ToggleButton/ToggleButton.xaml
+++ b/src/Wpf.Ui/Controls/ToggleButton/ToggleButton.xaml
@@ -10,7 +10,7 @@
- 11,5,11,6
+ 11,5,11,5
1
0,0,8,0
@@ -41,20 +41,24 @@
Height="{TemplateBinding Height}"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
- Padding="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Background="{TemplateBinding Background}"
- BorderBrush="{TemplateBinding BorderBrush}"
- BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding Border.CornerRadius}">
-
+
+
+
diff --git a/src/Wpf.Ui/Controls/ToggleSwitch/ToggleSwitch.xaml b/src/Wpf.Ui/Controls/ToggleSwitch/ToggleSwitch.xaml
index 5c397e420..cf737fee2 100644
--- a/src/Wpf.Ui/Controls/ToggleSwitch/ToggleSwitch.xaml
+++ b/src/Wpf.Ui/Controls/ToggleSwitch/ToggleSwitch.xaml
@@ -14,12 +14,10 @@
xmlns:controls="clr-namespace:Wpf.Ui.Controls"
xmlns:system="clr-namespace:System;assembly=System.Runtime">
-
-
1
40
20
- 8,6,0,0
+ 0,0,0,0
1
8,0,0,0
@@ -43,7 +41,7 @@
-
+
@@ -74,33 +72,35 @@
RadiusX="10"
RadiusY="10"
StrokeThickness="0" />
-
-
+ RadiusX="7"
+ RadiusY="7"
+ StrokeThickness="0">
+
-
-
-
+
+
-
+ RadiusX="7"
+ RadiusY="7"
+ StrokeThickness="0">
+
-
-
+
+
@@ -132,7 +134,7 @@
-
+
@@ -190,25 +192,25 @@
Duration="00:00:00.167" />
@@ -216,6 +218,12 @@
+
+
+
+
+
+
@@ -248,9 +256,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -258,9 +300,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -268,6 +324,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui/Controls/ToolTip/ToolTip.xaml b/src/Wpf.Ui/Controls/ToolTip/ToolTip.xaml
index bf9bd19e5..e1c8ad362 100644
--- a/src/Wpf.Ui/Controls/ToolTip/ToolTip.xaml
+++ b/src/Wpf.Ui/Controls/ToolTip/ToolTip.xaml
@@ -5,13 +5,18 @@
All Rights Reserved.
-->
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui/Controls/TreeView/TreeViewItem.xaml b/src/Wpf.Ui/Controls/TreeView/TreeViewItem.xaml
index 7a1fdb7f6..ec6c4bf05 100644
--- a/src/Wpf.Ui/Controls/TreeView/TreeViewItem.xaml
+++ b/src/Wpf.Ui/Controls/TreeView/TreeViewItem.xaml
@@ -97,7 +97,6 @@
-
-
diff --git a/src/Wpf.Ui/Controls/VirtualizingGridView/VirtualizingGridView.cs b/src/Wpf.Ui/Controls/VirtualizingGridView/VirtualizingGridView.cs
index b3acc4f57..634ac4416 100644
--- a/src/Wpf.Ui/Controls/VirtualizingGridView/VirtualizingGridView.cs
+++ b/src/Wpf.Ui/Controls/VirtualizingGridView/VirtualizingGridView.cs
@@ -105,7 +105,7 @@ protected virtual void InitializeItemsPanel()
{
Source = this,
Path = new PropertyPath(nameof(Orientation)),
- Mode = BindingMode.OneWay
+ Mode = BindingMode.OneWay,
}
);
factory.SetBinding(
@@ -114,7 +114,7 @@ protected virtual void InitializeItemsPanel()
{
Source = this,
Path = new PropertyPath(nameof(SpacingMode)),
- Mode = BindingMode.OneWay
+ Mode = BindingMode.OneWay,
}
);
factory.SetBinding(
@@ -123,7 +123,7 @@ protected virtual void InitializeItemsPanel()
{
Source = this,
Path = new PropertyPath(nameof(StretchItems)),
- Mode = BindingMode.OneWay
+ Mode = BindingMode.OneWay,
}
);
diff --git a/src/Wpf.Ui/Controls/Window/WindowBackdrop.cs b/src/Wpf.Ui/Controls/Window/WindowBackdrop.cs
index a1cc1c2d2..9eb42f385 100644
--- a/src/Wpf.Ui/Controls/Window/WindowBackdrop.cs
+++ b/src/Wpf.Ui/Controls/Window/WindowBackdrop.cs
@@ -3,7 +3,9 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
-using System.Runtime.InteropServices;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.Graphics.Dwm;
using Wpf.Ui.Appearance;
using Wpf.Ui.Interop;
@@ -28,7 +30,7 @@ public static bool IsSupported(WindowBackdropType backdropType)
WindowBackdropType.Mica => Win32.Utilities.IsOSWindows11OrNewer,
WindowBackdropType.Acrylic => Win32.Utilities.IsOSWindows7OrNewer,
WindowBackdropType.None => true,
- _ => false
+ _ => false,
};
}
@@ -38,7 +40,7 @@ public static bool IsSupported(WindowBackdropType backdropType)
/// The window to which the backdrop effect will be applied.
/// The type of backdrop effect to apply. Determines the visual appearance of the window's backdrop.
/// if the operation was successful; otherwise, .
- public static bool ApplyBackdrop(System.Windows.Window? window, WindowBackdropType backdropType)
+ public static bool ApplyBackdrop(Window? window, WindowBackdropType backdropType)
{
if (window is null)
{
@@ -59,8 +61,7 @@ public static bool ApplyBackdrop(System.Windows.Window? window, WindowBackdropTy
window.Loaded += (sender, _1) =>
{
- IntPtr windowHandle =
- new WindowInteropHelper(sender as System.Windows.Window ?? null)?.Handle ?? IntPtr.Zero;
+ IntPtr windowHandle = new WindowInteropHelper(sender as Window)?.Handle ?? IntPtr.Zero;
if (windowHandle == IntPtr.Zero)
{
@@ -86,7 +87,7 @@ public static bool ApplyBackdrop(IntPtr hWnd, WindowBackdropType backdropType)
return false;
}
- if (!User32.IsWindow(hWnd))
+ if (!PInvoke.IsWindow(new HWND(hWnd)))
{
return false;
}
@@ -115,12 +116,20 @@ public static bool ApplyBackdrop(IntPtr hWnd, WindowBackdropType backdropType)
return backdropType switch
{
- WindowBackdropType.Auto => ApplyDwmwWindowAttrubute(hWnd, Dwmapi.DWMSBT.DWMSBT_AUTO),
- WindowBackdropType.Mica => ApplyDwmwWindowAttrubute(hWnd, Dwmapi.DWMSBT.DWMSBT_MAINWINDOW),
- WindowBackdropType.Acrylic
- => ApplyDwmwWindowAttrubute(hWnd, Dwmapi.DWMSBT.DWMSBT_TRANSIENTWINDOW),
- WindowBackdropType.Tabbed => ApplyDwmwWindowAttrubute(hWnd, Dwmapi.DWMSBT.DWMSBT_TABBEDWINDOW),
- _ => ApplyDwmwWindowAttrubute(hWnd, Dwmapi.DWMSBT.DWMSBT_DISABLE),
+ WindowBackdropType.Auto => ApplyDwmwWindowAttribute(hWnd, DWM_SYSTEMBACKDROP_TYPE.DWMSBT_AUTO),
+ WindowBackdropType.Mica => ApplyDwmwWindowAttribute(
+ hWnd,
+ DWM_SYSTEMBACKDROP_TYPE.DWMSBT_MAINWINDOW
+ ),
+ WindowBackdropType.Acrylic => ApplyDwmwWindowAttribute(
+ hWnd,
+ DWM_SYSTEMBACKDROP_TYPE.DWMSBT_TRANSIENTWINDOW
+ ),
+ WindowBackdropType.Tabbed => ApplyDwmwWindowAttribute(
+ hWnd,
+ DWM_SYSTEMBACKDROP_TYPE.DWMSBT_TABBEDWINDOW
+ ),
+ _ => ApplyDwmwWindowAttribute(hWnd, DWM_SYSTEMBACKDROP_TYPE.DWMSBT_NONE),
};
}
@@ -128,7 +137,7 @@ public static bool ApplyBackdrop(IntPtr hWnd, WindowBackdropType backdropType)
/// Tries to remove backdrop effects if they have been applied to the .
///
/// The window from which the effect should be removed.
- public static bool RemoveBackdrop(System.Windows.Window? window)
+ public static bool RemoveBackdrop(Window? window)
{
if (window is null)
{
@@ -144,7 +153,7 @@ public static bool RemoveBackdrop(System.Windows.Window? window)
/// Tries to remove all effects if they have been applied to the hWnd.
///
/// Pointer to the window handle.
- public static bool RemoveBackdrop(IntPtr hWnd)
+ public static unsafe bool RemoveBackdrop(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)
{
@@ -158,26 +167,27 @@ public static bool RemoveBackdrop(IntPtr hWnd)
return false;
}
- if (!User32.IsWindow(hWnd))
+ if (!PInvoke.IsWindow(new HWND(hWnd)))
{
return false;
}
- var pvAttribute = 0; // Disable
- var backdropPvAttribute = (int)Dwmapi.DWMSBT.DWMSBT_DISABLE;
+ BOOL pvAttribute = false;
- _ = Dwmapi.DwmSetWindowAttribute(
- hWnd,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_MICA_EFFECT,
- ref pvAttribute,
- Marshal.SizeOf(typeof(int))
+ _ = PInvoke.DwmSetWindowAttribute(
+ new HWND(hWnd),
+ DWMWINDOWATTRIBUTE.DWMWA_MICA_EFFECT,
+ &pvAttribute,
+ (uint)sizeof(BOOL)
);
- _ = Dwmapi.DwmSetWindowAttribute(
- hWnd,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
- ref backdropPvAttribute,
- Marshal.SizeOf(typeof(int))
+ DWM_SYSTEMBACKDROP_TYPE backdropPvAttribute = DWM_SYSTEMBACKDROP_TYPE.DWMSBT_NONE;
+
+ _ = PInvoke.DwmSetWindowAttribute(
+ new HWND(hWnd),
+ DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
+ &backdropPvAttribute,
+ sizeof(DWM_SYSTEMBACKDROP_TYPE)
);
return true;
@@ -188,7 +198,7 @@ public static bool RemoveBackdrop(IntPtr hWnd)
///
/// Window to manipulate.
/// if operation was successful.
- public static bool RemoveBackground(System.Windows.Window? window)
+ public static bool RemoveBackground(Window? window)
{
if (window is null)
{
@@ -216,7 +226,7 @@ public static bool RemoveBackground(System.Windows.Window? window)
return true;
}
- public static bool RemoveTitlebarBackground(System.Windows.Window? window)
+ public static unsafe bool RemoveTitlebarBackground(Window? window)
{
if (window is null)
{
@@ -237,63 +247,53 @@ public static bool RemoveTitlebarBackground(System.Windows.Window? window)
{
// NOTE: https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
// Specifying DWMWA_COLOR_DEFAULT (value 0xFFFFFFFF) for the color will reset the window back to using the system's default behavior for the caption color.
- uint titlebarPvAttribute = 0xFFFFFFFE;
-
- Dwmapi.DwmSetWindowAttribute(
- windowSource.Handle,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_CAPTION_COLOR,
- ref titlebarPvAttribute,
- Marshal.SizeOf(typeof(uint))
- );
+ uint titlebarPvAttribute = PInvoke.DWMWA_COLOR_NONE;
+
+ return PInvoke.DwmSetWindowAttribute(
+ new HWND(windowSource.Handle),
+ DWMWINDOWATTRIBUTE.DWMWA_CAPTION_COLOR,
+ &titlebarPvAttribute,
+ sizeof(uint)
+ ) == HRESULT.S_OK;
}
return true;
}
- private static bool ApplyDwmwWindowAttrubute(IntPtr hWnd, Dwmapi.DWMSBT dwmSbt)
+ private static unsafe bool ApplyDwmwWindowAttribute(IntPtr hWnd, DWM_SYSTEMBACKDROP_TYPE dwmSbt)
{
if (hWnd == IntPtr.Zero)
{
return false;
}
- if (!User32.IsWindow(hWnd))
+ if (!PInvoke.IsWindow(new HWND(hWnd)))
{
return false;
}
- int backdropPvAttribute = (int)dwmSbt;
-
- var dwmApiResult = Dwmapi.DwmSetWindowAttribute(
- hWnd,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
- ref backdropPvAttribute,
- Marshal.SizeOf(typeof(int))
- );
+ DWM_SYSTEMBACKDROP_TYPE backdropPvAttribute = dwmSbt;
- return dwmApiResult == HRESULT.S_OK;
+ return PInvoke.DwmSetWindowAttribute(
+ new HWND(hWnd),
+ DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
+ &backdropPvAttribute,
+ sizeof(DWM_SYSTEMBACKDROP_TYPE)
+ ) == HRESULT.S_OK;
}
- private static bool ApplyLegacyMicaBackdrop(IntPtr hWnd)
+ private static unsafe bool ApplyLegacyMicaBackdrop(IntPtr hWnd)
{
- var backdropPvAttribute = 1; // Enable
-
- // TODO: Validate HRESULT
- var dwmApiResult = Dwmapi.DwmSetWindowAttribute(
- hWnd,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_MICA_EFFECT,
- ref backdropPvAttribute,
- Marshal.SizeOf(typeof(int))
- );
-
- return dwmApiResult == HRESULT.S_OK;
+ BOOL backdropPvAttribute = true;
+
+ return PInvoke.DwmSetWindowAttribute(
+ new HWND(hWnd),
+ DWMWINDOWATTRIBUTE.DWMWA_MICA_EFFECT,
+ &backdropPvAttribute,
+ (uint)sizeof(BOOL)
+ ) == HRESULT.S_OK;
}
- /*private static bool ApplyLegacyAcrylicBackdrop(IntPtr hWnd)
- {
- throw new NotImplementedException();
- }*/
-
private static bool RestoreContentBackground(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)
@@ -301,7 +301,7 @@ private static bool RestoreContentBackground(IntPtr hWnd)
return false;
}
- if (!User32.IsWindow(hWnd))
+ if (!PInvoke.IsWindow(new HWND(hWnd)))
{
return false;
}
@@ -314,7 +314,7 @@ private static bool RestoreContentBackground(IntPtr hWnd)
windowSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor;
}
- if (windowSource?.RootVisual is System.Windows.Window window)
+ if (windowSource?.RootVisual is Window window)
{
var backgroundBrush = window.Resources["ApplicationBackgroundBrush"];
@@ -334,18 +334,17 @@ private static SolidColorBrush GetFallbackBackgroundBrush()
{
return ApplicationThemeManager.GetAppTheme() switch
{
- ApplicationTheme.HighContrast
- => ApplicationThemeManager.GetSystemTheme() switch
- {
- SystemTheme.HC1 => new SolidColorBrush(Color.FromArgb(0xFF, 0x2D, 0x32, 0x36)),
- SystemTheme.HC2 => new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0x00, 0x00)),
- SystemTheme.HCBlack => new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20)),
- SystemTheme.HCWhite => new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20)),
- _ => new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFA, 0xEF)),
- },
+ ApplicationTheme.HighContrast => ApplicationThemeManager.GetSystemTheme() switch
+ {
+ SystemTheme.HC1 => new SolidColorBrush(Color.FromArgb(0xFF, 0x2D, 0x32, 0x36)),
+ SystemTheme.HC2 => new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0x00, 0x00)),
+ SystemTheme.HCBlack => new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20)),
+ SystemTheme.HCWhite => new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20)),
+ _ => new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFA, 0xEF)),
+ },
ApplicationTheme.Dark => new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20)),
ApplicationTheme.Light => new SolidColorBrush(Color.FromArgb(0xFF, 0xFA, 0xFA, 0xFA)),
- _ => new SolidColorBrush(Color.FromArgb(0xFF, 0xFA, 0xFA, 0xFA))
+ _ => new SolidColorBrush(Color.FromArgb(0xFF, 0xFA, 0xFA, 0xFA)),
};
}
}
diff --git a/src/Wpf.Ui/Controls/Window/WindowBackdropType.cs b/src/Wpf.Ui/Controls/Window/WindowBackdropType.cs
index df853c0ce..4f8db5c8b 100644
--- a/src/Wpf.Ui/Controls/Window/WindowBackdropType.cs
+++ b/src/Wpf.Ui/Controls/Window/WindowBackdropType.cs
@@ -31,5 +31,5 @@ public enum WindowBackdropType
///
/// Windows 11 wallpaper blur effect.
///
- Tabbed
+ Tabbed,
}
diff --git a/src/Wpf.Ui/Controls/Window/WindowCornerPreference.cs b/src/Wpf.Ui/Controls/Window/WindowCornerPreference.cs
index b0395e573..cfb2311db 100644
--- a/src/Wpf.Ui/Controls/Window/WindowCornerPreference.cs
+++ b/src/Wpf.Ui/Controls/Window/WindowCornerPreference.cs
@@ -29,5 +29,5 @@ public enum WindowCornerPreference
///
/// Round the corners slightly.
///
- RoundSmall
+ RoundSmall,
}
diff --git a/src/Wpf.Ui/Converters/BackButtonVisibilityToVisibilityConverter.cs b/src/Wpf.Ui/Converters/BackButtonVisibilityToVisibilityConverter.cs
index 2cd0f1d03..0309b8d93 100644
--- a/src/Wpf.Ui/Converters/BackButtonVisibilityToVisibilityConverter.cs
+++ b/src/Wpf.Ui/Converters/BackButtonVisibilityToVisibilityConverter.cs
@@ -18,7 +18,7 @@ public object Convert(object? value, Type targetType, object? parameter, Culture
NavigationViewBackButtonVisible.Collapsed => Visibility.Collapsed,
NavigationViewBackButtonVisible.Visible => Visibility.Visible,
NavigationViewBackButtonVisible.Auto => Visibility.Visible,
- _ => Visibility.Collapsed
+ _ => Visibility.Collapsed,
};
}
diff --git a/src/Wpf.Ui/Converters/BrushToColorConverter.cs b/src/Wpf.Ui/Converters/BrushToColorConverter.cs
index a35fa002b..4790766f1 100644
--- a/src/Wpf.Ui/Converters/BrushToColorConverter.cs
+++ b/src/Wpf.Ui/Converters/BrushToColorConverter.cs
@@ -27,7 +27,7 @@ public object Convert(object? value, Type targetType, object? parameter, Culture
A = 255,
R = 255,
G = 0,
- B = 0
+ B = 0,
};
}
diff --git a/src/Wpf.Ui/Converters/ClipConverter.cs b/src/Wpf.Ui/Converters/ClipConverter.cs
new file mode 100644
index 000000000..ae6d0112c
--- /dev/null
+++ b/src/Wpf.Ui/Converters/ClipConverter.cs
@@ -0,0 +1,39 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Windows.Data;
+
+namespace Wpf.Ui.Converters;
+
+public class ClipConverter : IMultiValueConverter
+{
+ ///
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (values.Length != 3)
+ {
+ return null;
+ }
+
+ if (
+ values[0] is not double width
+ || values[1] is not double height
+ || values[2] is not double percentage
+ )
+ {
+ return null;
+ }
+
+ double clippedWidth = width * percentage;
+
+ return new RectangleGeometry(new Rect(0, 0, clippedWidth, height));
+ }
+
+ ///
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/src/Wpf.Ui/Converters/CornerRadiusSplitConverter.cs b/src/Wpf.Ui/Converters/CornerRadiusSplitConverter.cs
new file mode 100644
index 000000000..184fa83fa
--- /dev/null
+++ b/src/Wpf.Ui/Converters/CornerRadiusSplitConverter.cs
@@ -0,0 +1,44 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+namespace Wpf.Ui.Converters;
+
+using System.Windows.Data;
+
+public class CornerRadiusSplitConverter : IMultiValueConverter
+{
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ var original = new CornerRadius(0);
+ if (values.Length > 0 && values[0] is CornerRadius cornerRadius)
+ {
+ original = cornerRadius;
+ }
+
+ bool isExpanded = false;
+ if (values.Length > 1 && values[1] is bool isExpand)
+ {
+ isExpanded = isExpand;
+ }
+
+ var side = (parameter as string) ?? "Top";
+
+ if (string.Equals(side, "Top", StringComparison.OrdinalIgnoreCase))
+ {
+ return isExpanded
+ ? new CornerRadius(original.TopLeft, original.TopRight, 0, 0)
+ : original;
+ }
+ else
+ {
+ return isExpanded
+ ? new CornerRadius(0, 0, original.BottomRight, original.BottomLeft)
+ : new CornerRadius(0);
+ }
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ => throw new NotSupportedException();
+}
diff --git a/src/Wpf.Ui/Converters/DatePickerButtonPaddingConverter.cs b/src/Wpf.Ui/Converters/DatePickerButtonPaddingConverter.cs
new file mode 100644
index 000000000..68ace4546
--- /dev/null
+++ b/src/Wpf.Ui/Converters/DatePickerButtonPaddingConverter.cs
@@ -0,0 +1,33 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Windows.Data;
+
+namespace Wpf.Ui.Converters;
+
+internal class DatePickerButtonPaddingConverter : IMultiValueConverter
+{
+ ///
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (values is [Thickness padding, Thickness buttonMargin, double buttonWidth])
+ {
+ return new Thickness(
+ padding.Left,
+ padding.Top,
+ padding.Right + buttonMargin.Left + buttonMargin.Right + buttonWidth,
+ padding.Bottom
+ );
+ }
+
+ return default(Thickness);
+ }
+
+ ///
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/src/Wpf.Ui/Converters/FallbackBrushConverter.cs b/src/Wpf.Ui/Converters/FallbackBrushConverter.cs
index cec13b2be..5c2d785f0 100644
--- a/src/Wpf.Ui/Converters/FallbackBrushConverter.cs
+++ b/src/Wpf.Ui/Converters/FallbackBrushConverter.cs
@@ -15,7 +15,7 @@ public object Convert(object? value, Type targetType, object? parameter, Culture
{
SolidColorBrush brush => brush,
Color color => new SolidColorBrush(color),
- _ => new SolidColorBrush(Colors.Red)
+ _ => new SolidColorBrush(Colors.Red),
};
}
diff --git a/src/Wpf.Ui/Extensions/ColorExtensions.cs b/src/Wpf.Ui/Extensions/ColorExtensions.cs
index 0eb71c2de..f3f5bddc9 100644
--- a/src/Wpf.Ui/Extensions/ColorExtensions.cs
+++ b/src/Wpf.Ui/Extensions/ColorExtensions.cs
@@ -464,7 +464,7 @@ private static float ToPercentage(float value)
{
> 100f => 100f,
< 0f => 0f,
- _ => value
+ _ => value,
};
}
diff --git a/src/Wpf.Ui/Extensions/ContentDialogServiceExtensions.cs b/src/Wpf.Ui/Extensions/ContentDialogServiceExtensions.cs
index 56dfc90c7..77c562089 100644
--- a/src/Wpf.Ui/Extensions/ContentDialogServiceExtensions.cs
+++ b/src/Wpf.Ui/Extensions/ContentDialogServiceExtensions.cs
@@ -50,7 +50,7 @@ public static Task ShowSimpleDialogAsync(
Content = options.Content,
CloseButtonText = options.CloseButtonText,
PrimaryButtonText = options.PrimaryButtonText,
- SecondaryButtonText = options.SecondaryButtonText
+ SecondaryButtonText = options.SecondaryButtonText,
};
return dialogService.ShowAsync(dialog, cancellationToken);
diff --git a/src/Wpf.Ui/Extensions/PInvokeExtensions.cs b/src/Wpf.Ui/Extensions/PInvokeExtensions.cs
new file mode 100644
index 000000000..aec029fe5
--- /dev/null
+++ b/src/Wpf.Ui/Extensions/PInvokeExtensions.cs
@@ -0,0 +1,25 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using Windows.Win32.Graphics.Dwm;
+
+namespace Wpf.Ui.Extensions;
+
+internal static class PInvokeExtensions
+{
+ extension(DWMWINDOWATTRIBUTE attr)
+ {
+ ///
+ /// Gets the undocumented window attribute for enabling Mica effect on a window.
+ ///
+ public static DWMWINDOWATTRIBUTE DWMWA_MICA_EFFECT => (DWMWINDOWATTRIBUTE)1029;
+
+ ///
+ /// Gets the window attribute used to enable immersive dark mode prior to Windows 11.
+ ///
+ public static DWMWINDOWATTRIBUTE DMWA_USE_IMMERSIVE_DARK_MODE_OLD =>
+ DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE - 1;
+ }
+}
diff --git a/src/Wpf.Ui/Extensions/StringExtensions.cs b/src/Wpf.Ui/Extensions/StringExtensions.cs
new file mode 100644
index 000000000..fe4341769
--- /dev/null
+++ b/src/Wpf.Ui/Extensions/StringExtensions.cs
@@ -0,0 +1,26 @@
+īģŋ// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+#if NETFRAMEWORK
+using System.Diagnostics.Contracts;
+
+namespace Wpf.Ui.Extensions;
+
+internal static class StringExtensions
+{
+ ///
+ /// Returns a value indicating whether a specified string occurs within this string, using the specified comparison rules.
+ ///
+ /// Source string.
+ /// The string to seek.
+ /// One of the enumeration values that specifies the rules to use in the comparison.
+ /// true if the value parameter occurs within this string, or if value is the empty string (""); otherwise, false.
+ [Pure]
+ public static bool Contains(this string source, string value, StringComparison comparison)
+ {
+ return source.IndexOf(value, comparison) >= 0;
+ }
+}
+#endif
diff --git a/src/Wpf.Ui/Extensions/TextBlockFontTypographyExtensions.cs b/src/Wpf.Ui/Extensions/TextBlockFontTypographyExtensions.cs
index dcd519a7f..d162a35a7 100644
--- a/src/Wpf.Ui/Extensions/TextBlockFontTypographyExtensions.cs
+++ b/src/Wpf.Ui/Extensions/TextBlockFontTypographyExtensions.cs
@@ -27,7 +27,7 @@ public static string ToResourceValue(this FontTypography typography)
FontTypography.Title => "TitleTextBlockStyle",
FontTypography.TitleLarge => "TitleLargeTextBlockStyle",
FontTypography.Display => "DisplayTextBlockStyle",
- _ => throw new ArgumentOutOfRangeException(nameof(typography), typography, null)
+ _ => throw new ArgumentOutOfRangeException(nameof(typography), typography, null),
};
}
}
diff --git a/src/Wpf.Ui/Extensions/TextColorExtensions.cs b/src/Wpf.Ui/Extensions/TextColorExtensions.cs
index 725417384..e1cb621a9 100644
--- a/src/Wpf.Ui/Extensions/TextColorExtensions.cs
+++ b/src/Wpf.Ui/Extensions/TextColorExtensions.cs
@@ -24,7 +24,7 @@ public static string ToResourceValue(this TextColor textColor)
TextColor.Secondary => "TextFillColorSecondaryBrush",
TextColor.Tertiary => "TextFillColorTertiaryBrush",
TextColor.Disabled => "TextFillColorDisabledBrush",
- _ => throw new ArgumentOutOfRangeException(nameof(textColor), textColor, null)
+ _ => throw new ArgumentOutOfRangeException(nameof(textColor), textColor, null),
};
}
}
diff --git a/src/Wpf.Ui/Extensions/UiElementExtensions.cs b/src/Wpf.Ui/Extensions/UiElementExtensions.cs
index 164c54e3a..452c46686 100644
--- a/src/Wpf.Ui/Extensions/UiElementExtensions.cs
+++ b/src/Wpf.Ui/Extensions/UiElementExtensions.cs
@@ -10,7 +10,7 @@ internal static class UiElementExtensions
///
/// Do not call it outside of NCHITTEST, NCLBUTTONUP, NCLBUTTONDOWN messages!
///
- /// if mouse is over the element. otherwise.
+ /// if mouse is over the element. otherwise.
public static bool IsMouseOverElement(this UIElement element, IntPtr lParam)
{
// This method will be invoked very often and must be as simple as possible.
@@ -21,12 +21,21 @@ public static bool IsMouseOverElement(this UIElement element, IntPtr lParam)
try
{
- var mousePosScreen = new Point(Get_X_LParam(lParam), Get_Y_LParam(lParam));
- var bounds = new Rect(default, element.RenderSize);
+ // Ensure the visual is connected to a presentation source (needed for PointFromScreen).
+ if (PresentationSource.FromVisual(element) == null)
+ {
+ return false;
+ }
- Point mousePosRelative = element.PointFromScreen(mousePosScreen);
+ var mousePosition = new Point(Get_X_LParam(lParam), Get_Y_LParam(lParam));
- return bounds.Contains(mousePosRelative);
+ // If element is Panel, check if children at mousePosition is with IsHitTestVisible false.
+ return new Rect(default, element.RenderSize).Contains(element.PointFromScreen(mousePosition))
+ && element.IsHitTestVisible
+ && (
+ element is not System.Windows.Controls.Panel panel
+ || IsChildHitTestVisibleAtPointFromScreen(panel, mousePosition)
+ );
}
catch
{
@@ -43,4 +52,20 @@ private static int Get_Y_LParam(IntPtr lParam)
{
return (short)(lParam.ToInt32() >> 16);
}
+
+ private static bool IsChildHitTestVisibleAtPointFromScreen(
+ System.Windows.Controls.Panel panel,
+ Point mousePosition
+ )
+ {
+ foreach (UIElement child in panel.Children)
+ {
+ if (new Rect(default, child.RenderSize).Contains(child.PointFromScreen(mousePosition)))
+ {
+ return child.IsHitTestVisible;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/src/Wpf.Ui/GlobalUsings.cs b/src/Wpf.Ui/GlobalUsings.cs
index d8d8592ff..5f3d7e047 100644
--- a/src/Wpf.Ui/GlobalUsings.cs
+++ b/src/Wpf.Ui/GlobalUsings.cs
@@ -13,3 +13,4 @@
global using System.Windows;
global using System.Windows.Interop;
global using System.Windows.Media;
+global using Wpf.Ui.Extensions;
diff --git a/src/Wpf.Ui/Hardware/DpiHelper.cs b/src/Wpf.Ui/Hardware/DpiHelper.cs
index 335776bed..f8807ef57 100644
--- a/src/Wpf.Ui/Hardware/DpiHelper.cs
+++ b/src/Wpf.Ui/Hardware/DpiHelper.cs
@@ -3,6 +3,8 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
+using Windows.Win32;
+using Windows.Win32.Foundation;
using Wpf.Ui.Interop;
namespace Wpf.Ui.Hardware;
@@ -34,11 +36,11 @@ internal static class DpiHelper
/// Gets DPI of the selected .
///
/// The window that you want to get information about.
- public static Hardware.DisplayDpi GetWindowDpi(Window? window)
+ public static DisplayDpi GetWindowDpi(Window? window)
{
if (window is null)
{
- return new Hardware.DisplayDpi(DefaultDpi, DefaultDpi);
+ return new DisplayDpi(DefaultDpi, DefaultDpi);
}
return GetWindowDpi(new WindowInteropHelper(window).Handle);
@@ -48,16 +50,16 @@ public static Hardware.DisplayDpi GetWindowDpi(Window? window)
/// Gets DPI of the selected based on it's handle.
///
/// Handle of the window that you want to get information about.
- public static Hardware.DisplayDpi GetWindowDpi(IntPtr windowHandle)
+ public static DisplayDpi GetWindowDpi(IntPtr windowHandle)
{
if (windowHandle == IntPtr.Zero || !UnsafeNativeMethods.IsValidWindow(windowHandle))
{
- return new Hardware.DisplayDpi(DefaultDpi, DefaultDpi);
+ return new DisplayDpi(DefaultDpi, DefaultDpi);
}
- var windowDpi = (int)User32.GetDpiForWindow(windowHandle);
+ var windowDpi = (int)PInvoke.GetDpiForWindow(new HWND(windowHandle));
- return new Hardware.DisplayDpi(windowDpi, windowDpi);
+ return new DisplayDpi(windowDpi, windowDpi);
}
// TODO: Look into utilizing preprocessor symbols for more functionality
@@ -76,7 +78,7 @@ public static Hardware.DisplayDpi GetWindowDpi(IntPtr windowHandle)
/// Gets the DPI values from .
///
/// The DPI values from . If the property cannot be accessed, the default value is returned.
- public static Hardware.DisplayDpi GetSystemDpi()
+ public static DisplayDpi GetSystemDpi()
{
System.Reflection.PropertyInfo? dpiXProperty = typeof(SystemParameters).GetProperty(
"DpiX",
@@ -85,7 +87,7 @@ public static Hardware.DisplayDpi GetSystemDpi()
if (dpiXProperty == null)
{
- return new Hardware.DisplayDpi(DefaultDpi, DefaultDpi);
+ return new DisplayDpi(DefaultDpi, DefaultDpi);
}
System.Reflection.PropertyInfo? dpiYProperty = typeof(SystemParameters).GetProperty(
@@ -95,10 +97,10 @@ public static Hardware.DisplayDpi GetSystemDpi()
if (dpiYProperty == null)
{
- return new Hardware.DisplayDpi(DefaultDpi, DefaultDpi);
+ return new DisplayDpi(DefaultDpi, DefaultDpi);
}
- return new Hardware.DisplayDpi(
+ return new DisplayDpi(
(int)dpiXProperty.GetValue(null, null)!,
(int)dpiYProperty.GetValue(null, null)!
);
diff --git a/src/Wpf.Ui/Hardware/RenderingTier.cs b/src/Wpf.Ui/Hardware/RenderingTier.cs
index 354227d42..0af3f85fb 100644
--- a/src/Wpf.Ui/Hardware/RenderingTier.cs
+++ b/src/Wpf.Ui/Hardware/RenderingTier.cs
@@ -29,5 +29,5 @@ public enum RenderingTier
/// necessary system resources have not been exhausted.
/// This corresponds to a DirectX version that is greater than or equal to 9.0.
///
- FullAcceleration = 0x2
+ FullAcceleration = 0x2,
}
diff --git a/src/Wpf.Ui/Interop/Dwmapi.cs b/src/Wpf.Ui/Interop/Dwmapi.cs
deleted file mode 100644
index adf6a9618..000000000
--- a/src/Wpf.Ui/Interop/Dwmapi.cs
+++ /dev/null
@@ -1,678 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-// This Source Code is partially based on reverse engineering of the Windows Operating System,
-// and is intended for use on Windows systems only.
-// This Source Code is partially based on the source code provided by the .NET Foundation.
-//
-// NOTE:
-// I split unmanaged code stuff into the NativeMethods library.
-// If you have suggestions for the code below, please submit your changes there.
-// https://github.com/lepoco/nativemethods
-//
-// Windows Kits\10\Include\10.0.22000.0\um\dwmapi.h
-
-// ReSharper disable IdentifierTypo
-// ReSharper disable InconsistentNaming
-#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
-
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop;
-
-///
-/// Desktop Window Manager (DWM).
-///
-internal static class Dwmapi
-{
- ///
- /// Cloaked flags describing why a window is cloaked.
- ///
- public enum DWM_CLOAKED
- {
- DWM_CLOAKED_APP = 0x00000001,
- DWM_CLOAKED_SHELL = 0x00000002,
- DWM_CLOAKED_INHERITED = 0x00000004
- }
-
- ///
- /// GT_*
- ///
- public enum GESTURE_TYPE
- {
- GT_PEN_TAP = 0,
- GT_PEN_DOUBLETAP = 1,
- GT_PEN_RIGHTTAP = 2,
- GT_PEN_PRESSANDHOLD = 3,
- GT_PEN_PRESSANDHOLDABORT = 4,
- GT_TOUCH_TAP = 5,
- GT_TOUCH_DOUBLETAP = 6,
- GT_TOUCH_RIGHTTAP = 7,
- GT_TOUCH_PRESSANDHOLD = 8,
- GT_TOUCH_PRESSANDHOLDABORT = 9,
- GT_TOUCH_PRESSANDTAP = 10,
- }
-
- ///
- /// DWMTWR_* Tab window requirements.
- ///
- public enum DWM_TAB_WINDOW_REQUIREMENTS
- {
- ///
- /// This result means the window meets all requirements requested.
- ///
- DWMTWR_NONE = 0x0000,
-
- ///
- /// In some configurations, admin/user setting or mode of the system means that windows won't be tabbed
- /// This requirement says that the system/mode must implement tabbing and if it does not
- /// nothing can be done to change this.
- ///
- DWMTWR_IMPLEMENTED_BY_SYSTEM = 0x0001,
-
- ///
- /// The window has an owner or parent so is ineligible for tabbing.
- ///
- DWMTWR_WINDOW_RELATIONSHIP = 0x0002,
-
- ///
- /// The window has styles that make it ineligible for tabbing.
- /// To be eligible windows must:
- /// Have the WS_OVERLAPPEDWINDOW (WS_CAPTION, WS_THICKFRAME, etc.) styles set.
- /// Not have WS_POPUP, WS_CHILD or WS_DLGFRAME set.
- /// Not have WS_EX_TOPMOST or WS_EX_TOOLWINDOW set.
- ///
- DWMTWR_WINDOW_STYLES = 0x0004,
-
- // The window has a region (set using SetWindowRgn) making it ineligible.
- DWMTWR_WINDOW_REGION = 0x0008,
-
- ///
- /// The window is ineligible due to its Dwm configuration.
- /// It must not extended its client area into the title bar using DwmExtendFrameIntoClientArea
- /// It must not have DWMWA_NCRENDERING_POLICY set to DWMNCRP_ENABLED
- ///
- DWMTWR_WINDOW_DWM_ATTRIBUTES = 0x0010,
-
- ///
- /// The window is ineligible due to it's margins, most likely due to custom handling in WM_NCCALCSIZE.
- /// The window must use the default window margins for the non-client area.
- ///
- DWMTWR_WINDOW_MARGINS = 0x0020,
-
- ///
- /// The window has been explicitly opted out by setting DWMWA_TABBING_ENABLED to FALSE.
- ///
- DWMTWR_TABBING_ENABLED = 0x0040,
-
- ///
- /// The user has configured this application to not participate in tabbing.
- ///
- DWMTWR_USER_POLICY = 0x0080,
-
- ///
- /// The group policy has configured this application to not participate in tabbing.
- ///
- DWMTWR_GROUP_POLICY = 0x0100,
-
- ///
- /// This is set if app compat has blocked tabs for this window. Can be overridden per window by setting
- /// DWMWA_TABBING_ENABLED to TRUE. That does not override any other tabbing requirements.
- ///
- DWMTWR_APP_COMPAT = 0x0200
- }
-
- ///
- /// Flags used by the DwmSetWindowAttribute function to specify the rounded corner preference for a window.
- ///
- [Flags]
- public enum DWM_WINDOW_CORNER_PREFERENCE
- {
- DEFAULT = 0,
- DONOTROUND = 1,
- ROUND = 2,
- ROUNDSMALL = 3
- }
-
- ///
- /// Backdrop types.
- ///
- [Flags]
- public enum DWMSBT : uint
- {
- ///
- /// Automatically selects backdrop effect.
- ///
- DWMSBT_AUTO = 0,
-
- ///
- /// Turns off the backdrop effect.
- ///
- DWMSBT_DISABLE = 1,
-
- ///
- /// Sets Mica effect with generated wallpaper tint.
- ///
- DWMSBT_MAINWINDOW = 2,
-
- ///
- /// Sets acrlic effect.
- ///
- DWMSBT_TRANSIENTWINDOW = 3,
-
- ///
- /// Sets blurred wallpaper effect, like Mica without tint.
- ///
- DWMSBT_TABBEDWINDOW = 4
- }
-
- ///
- /// Non-client rendering policy attribute values
- ///
- public enum DWMNCRENDERINGPOLICY
- {
- ///
- /// Enable/disable non-client rendering based on window style
- ///
- DWMNCRP_USEWINDOWSTYLE,
-
- ///
- /// Disabled non-client rendering; window style is ignored
- ///
- DWMNCRP_DISABLED,
-
- ///
- /// Enabled non-client rendering; window style is ignored
- ///
- DWMNCRP_ENABLED,
-
- ///
- /// Sentinel value.
- ///
- DWMNCRP_LAST
- }
-
- ///
- /// Values designating how Flip3D treats a given window.
- ///
- public enum DWMFLIP3DWINDOWPOLICY
- {
- ///
- /// Hide or include the window in Flip3D based on window style and visibility.
- ///
- DWMFLIP3D_DEFAULT,
-
- ///
- /// Display the window under Flip3D and disabled.
- ///
- DWMFLIP3D_EXCLUDEBELOW,
-
- ///
- /// Display the window above Flip3D and enabled.
- ///
- DWMFLIP3D_EXCLUDEABOVE,
-
- ///
- /// Sentinel value.
- ///
- DWMFLIP3D_LAST
- }
-
- ///
- /// Options used by the DwmGetWindowAttribute and DwmSetWindowAttribute functions.
- ///
- ///
- [Flags]
- public enum DWMWINDOWATTRIBUTE
- {
- ///
- /// Is non-client rendering enabled/disabled
- ///
- DWMWA_NCRENDERING_ENABLED = 1,
-
- ///
- /// DWMNCRENDERINGPOLICY - Non-client rendering policy
- ///
- DWMWA_NCRENDERING_POLICY = 2,
-
- ///
- /// Potentially enable/forcibly disable transitions
- ///
- DWMWA_TRANSITIONS_FORCEDISABLED = 3,
-
- ///
- /// Enables content rendered in the non-client area to be visible on the frame drawn by DWM.
- ///
- DWMWA_ALLOW_NCPAINT = 4,
-
- ///
- /// Retrieves the bounds of the caption button area in the window-relative space.
- ///
- DWMWA_CAPTION_BUTTON_BOUNDS = 5,
-
- ///
- /// Is non-client content RTL mirrored
- ///
- DWMWA_NONCLIENT_RTL_LAYOUT = 6,
-
- ///
- /// Forces the window to display an iconic thumbnail or peek representation (a static bitmap), even if a live or snapshot representation of the window is available.
- ///
- DWMWA_FORCE_ICONIC_REPRESENTATION = 7,
-
- ///
- /// Designates how Flip3D will treat the window.
- ///
- DWMWA_FLIP3D_POLICY = 8,
-
- ///
- /// Gets the extended frame bounds rectangle in screen space
- ///
- DWMWA_EXTENDED_FRAME_BOUNDS = 9,
-
- ///
- /// Indicates an available bitmap when there is no better thumbnail representation.
- ///
- DWMWA_HAS_ICONIC_BITMAP = 10,
-
- ///
- /// Don't invoke Peek on the window.
- ///
- DWMWA_DISALLOW_PEEK = 11,
-
- ///
- /// LivePreview exclusion information
- ///
- DWMWA_EXCLUDED_FROM_PEEK = 12,
-
- ///
- /// Cloaks the window such that it is not visible to the user.
- ///
- DWMWA_CLOAK = 13,
-
- ///
- /// If the window is cloaked, provides one of the following values explaining why.
- ///
- DWMWA_CLOAKED = 14,
-
- ///
- /// Freeze the window's thumbnail image with its current visuals. Do no further live updates on the thumbnail image to match the window's contents.
- ///
- DWMWA_FREEZE_REPRESENTATION = 15,
-
- ///
- /// BOOL, Updates the window only when desktop composition runs for other reasons
- ///
- DWMWA_PASSIVE_UPDATE_MODE = 16,
-
- ///
- /// BOOL, Allows the use of host backdrop brushes for the window.
- ///
- DWMWA_USE_HOSTBACKDROPBRUSH = 17,
-
- ///
- /// Allows a window to either use the accent color, or dark, according to the user Color Mode preferences.
- ///
- DMWA_USE_IMMERSIVE_DARK_MODE_OLD = 19,
-
- ///
- /// Allows a window to either use the accent color, or dark, according to the user Color Mode preferences.
- ///
- DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
-
- ///
- /// Controls the policy that rounds top-level window corners.
- /// Windows 11 and above.
- ///
- DWMWA_WINDOW_CORNER_PREFERENCE = 33,
-
- ///
- /// The color of the thin border around a top-level window.
- ///
- DWMWA_BORDER_COLOR = 34,
-
- ///
- /// The color of the caption.
- /// Windows 11 and above.
- ///
- DWMWA_CAPTION_COLOR = 35,
-
- ///
- /// The color of the caption text.
- /// Windows 11 and above.
- ///
- DWMWA_TEXT_COLOR = 36,
-
- ///
- /// Width of the visible border around a thick frame window.
- /// Windows 11 and above.
- ///
- DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37,
-
- ///
- /// Allows to enter a value from 0 to 4 deciding on the imposed backdrop effect.
- ///
- DWMWA_SYSTEMBACKDROP_TYPE = 38,
-
- ///
- /// Indicates whether the window should use the Mica effect.
- /// Windows 11 and above.
- ///
- DWMWA_MICA_EFFECT = 1029
- }
-
- ///
- /// Represents the current DWM color accent settings.
- ///
- [StructLayout(LayoutKind.Sequential)]
- public struct DWMCOLORIZATIONPARAMS
- {
- ///
- /// ColorizationColor
- ///
- public uint clrColor;
-
- ///
- /// ColorizationAfterglow.
- ///
- public uint clrAfterGlow;
-
- ///
- /// ColorizationColorBalance.
- ///
- public uint nIntensity;
-
- ///
- /// ColorizationAfterglowBalance.
- ///
- public uint clrAfterGlowBalance;
-
- ///
- /// ColorizationBlurBalance.
- ///
- public uint clrBlurBalance;
-
- ///
- /// ColorizationGlassReflectionIntensity.
- ///
- public uint clrGlassReflectionIntensity;
-
- ///
- /// ColorizationOpaqueBlend.
- ///
- public bool fOpaque;
- }
-
- ///
- /// Defines a data type used by the Desktop Window Manager (DWM) APIs. It represents a generic ratio and is used for different purposes and units even within a single API.
- ///
- [StructLayout(LayoutKind.Sequential)]
- public struct UNSIGNED_RATIO
- {
- ///
- /// The ratio numerator.
- ///
- public uint uiNumerator;
-
- ///
- /// The ratio denominator.
- ///
- public uint uiDenominator;
- }
-
- ///
- /// Specifies the input operations for which visual feedback should be provided. This enumeration is used by the DwmShowContact function.
- ///
- public enum DWM_SHOWCONTACT
- {
- DWMSC_DOWN,
- DWMSC_UP,
- DWMSC_DRAG,
- DWMSC_HOLD,
- DWMSC_PENBARREL,
- DWMSC_NONE,
- DWMSC_ALL
- }
-
- ///
- /// Flags used by the DwmSetPresentParameters function to specify the frame sampling type.
- ///
- public enum DWM_SOURCE_FRAME_SAMPLING
- {
- ///
- /// Use the first source frame that includes the first refresh of the output frame
- ///
- DWM_SOURCE_FRAME_SAMPLING_POINT,
-
- ///
- /// Use the source frame that includes the most refreshes of out the output frame
- /// in case of multiple source frames with the same coverage the last will be used
- ///
- DWM_SOURCE_FRAME_SAMPLING_COVERAGE,
-
- ///
- /// Sentinel value.
- ///
- DWM_SOURCE_FRAME_SAMPLING_LAST
- }
-
- ///
- /// Specifies Desktop Window Manager (DWM) composition timing information. Used by the function.
- ///
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct DWM_TIMING_INFO
- {
- public int cbSize;
- public UNSIGNED_RATIO rateRefresh;
- public ulong qpcRefreshPeriod;
- public UNSIGNED_RATIO rateCompose;
- public ulong qpcVBlank;
- public ulong cRefresh;
- public uint cDXRefresh;
- public ulong qpcCompose;
- public ulong cFrame;
- public uint cDXPresent;
- public ulong cRefreshFrame;
- public ulong cFrameSubmitted;
- public uint cDXPresentSubmitted;
- public ulong cFrameConfirmed;
- public uint cDXPresentConfirmed;
- public ulong cRefreshConfirmed;
- public uint cDXRefreshConfirmed;
- public ulong cFramesLate;
- public uint cFramesOutstanding;
- public ulong cFrameDisplayed;
- public ulong qpcFrameDisplayed;
- public ulong cRefreshFrameDisplayed;
- public ulong cFrameComplete;
- public ulong qpcFrameComplete;
- public ulong cFramePending;
- public ulong qpcFramePending;
- public ulong cFramesDisplayed;
- public ulong cFramesComplete;
- public ulong cFramesPending;
- public ulong cFramesAvailable;
- public ulong cFramesDropped;
- public ulong cFramesMissed;
- public ulong cRefreshNextDisplayed;
- public ulong cRefreshNextPresented;
- public ulong cRefreshesDisplayed;
- public ulong cRefreshesPresented;
- public ulong cRefreshStarted;
- public ulong cPixelsReceived;
- public ulong cPixelsDrawn;
- public ulong cBuffersEmpty;
- }
-
- ///
- /// SIT flags.
- ///
- public enum DWM_SIT
- {
- ///
- /// None.
- ///
- NONE,
-
- ///
- /// Displays a frame around the provided bitmap.
- ///
- DISPLAYFRAME = 1,
- }
-
- ///
- /// Obtains a value that indicates whether Desktop Window Manager (DWM) composition is enabled.
- ///
- /// A pointer to a value that, when this function returns successfully, receives TRUE if DWM composition is enabled; otherwise, FALSE.
- /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
- [DllImport(Libraries.Dwmapi, BestFitMapping = false)]
- public static extern int DwmIsCompositionEnabled([Out] out int pfEnabled);
-
- ///
- /// Extends the window frame into the client area.
- ///
- /// The handle to the window in which the frame will be extended into the client area.
- /// A pointer to a MARGINS structure that describes the margins to use when extending the frame into the client area.
- [DllImport(Libraries.Dwmapi, PreserveSig = false)]
- public static extern void DwmExtendFrameIntoClientArea(
- [In] IntPtr hWnd,
- [In] ref UxTheme.MARGINS pMarInset
- );
-
- ///
- /// Retrieves the current composition timing information for a specified window.
- ///
- /// The handle to the window for which the composition timing information should be retrieved.
- /// A pointer to a structure that, when this function returns successfully, receives the current composition timing information for the window.
- [DllImport(Libraries.Dwmapi)]
- public static extern void DwmGetCompositionTimingInfo(
- [In] IntPtr hWnd,
- [In] ref DWM_TIMING_INFO pTimingInfo
- );
-
- ///
- /// Called by an application to indicate that all previously provided iconic bitmaps from a window, both thumbnails and peek representations, should be refreshed.
- ///
- /// A handle to the window or tab whose bitmaps are being invalidated through this call. This window must belong to the calling process.
- [DllImport(Libraries.Dwmapi, PreserveSig = false)]
- public static extern void DwmInvalidateIconicBitmaps([In] IntPtr hWnd);
-
- ///
- /// Sets a static, iconic bitmap on a window or tab to use as a thumbnail representation. The taskbar can use this bitmap as a thumbnail switch target for the window or tab.
- ///
- /// A handle to the window or tab. This window must belong to the calling process.
- /// A handle to the bitmap to represent the window that hwnd specifies.
- /// The display options for the thumbnail.
- [DllImport(Libraries.Dwmapi, PreserveSig = false)]
- public static extern void DwmSetIconicThumbnail(
- [In] IntPtr hWnd,
- [In] IntPtr hbmp,
- [In] DWM_SIT dwSITFlags
- );
-
- ///
- /// Sets a static, iconic bitmap to display a live preview (also known as a Peek preview) of a window or tab. The taskbar can use this bitmap to show a full-sized preview of a window or tab.
- ///
- /// A handle to the window. This window must belong to the calling process.
- /// A handle to the bitmap to represent the window that hwnd specifies.
- /// The offset of a tab window's client region (the content area inside the client window frame) from the host window's frame. This offset enables the tab window's contents to be drawn correctly in a live preview when it is drawn without its frame.
- /// The display options for the live preview.
- [DllImport(Libraries.Dwmapi, PreserveSig = false)]
- public static extern int DwmSetIconicLivePreviewBitmap(
- [In] IntPtr hWnd,
- [In] IntPtr hbmp,
- [In, Optional] WinDef.POINT pptClient,
- [In] DWM_SIT dwSITFlags
- );
-
- ///
- /// Sets the value of Desktop Window Manager (DWM) non-client rendering attributes for a window.
- ///
- /// The handle to the window for which the attribute value is to be set.
- /// A flag describing which value to set, specified as a value of the DWMWINDOWATTRIBUTE enumeration.
- /// A pointer to an object containing the attribute value to set.
- /// The size, in bytes, of the attribute value being set via the pvAttribute parameter.
- /// If the function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
- [DllImport(Libraries.Dwmapi)]
- public static extern int DwmSetWindowAttribute(
- [In] IntPtr hWnd,
- [In] int dwAttribute,
- [In] ref int pvAttribute,
- [In] int cbAttribute
- );
-
- ///
- /// Sets the value of Desktop Window Manager (DWM) non-client rendering attributes for a window.
- ///
- /// The handle to the window for which the attribute value is to be set.
- /// A flag describing which value to set, specified as a value of the DWMWINDOWATTRIBUTE enumeration.
- /// A pointer to an object containing the attribute value to set.
- /// The size, in bytes, of the attribute value being set via the pvAttribute parameter.
- /// If the function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
- [DllImport(Libraries.Dwmapi)]
- public static extern int DwmSetWindowAttribute(
- [In] IntPtr hWnd,
- [In] DWMWINDOWATTRIBUTE dwAttribute,
- [In] ref int pvAttribute,
- [In] int cbAttribute
- );
-
- ///
- /// Sets the value of Desktop Window Manager (DWM) non-client rendering attributes for a window.
- ///
- /// The handle to the window for which the attribute value is to be set.
- /// A flag describing which value to set, specified as a value of the DWMWINDOWATTRIBUTE enumeration.
- /// A pointer to an object containing the attribute value to set.
- /// The size, in bytes, of the attribute value being set via the pvAttribute parameter.
- /// If the function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
- [DllImport(Libraries.Dwmapi)]
- public static extern int DwmSetWindowAttribute(
- [In] IntPtr hWnd,
- [In] DWMWINDOWATTRIBUTE dwAttribute,
- [In] ref uint pvAttribute,
- [In] int cbAttribute
- );
-
- ///
- /// Retrieves the current value of a specified Desktop Window Manager (DWM) attribute applied to a window. For programming guidance, and code examples, see Controlling non-client region rendering.
- ///
- /// The handle to the window from which the attribute value is to be retrieved.
- /// A flag describing which value to retrieve, specified as a value of the enumeration.
- /// A pointer to a value which, when this function returns successfully, receives the current value of the attribute. The type of the retrieved value depends on the value of the dwAttribute parameter.
- /// The size, in bytes, of the attribute value being received via the pvAttribute parameter.
- /// If the function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
- [DllImport(Libraries.Dwmapi)]
- public static extern int DwmGetWindowAttribute(
- [In] IntPtr hWnd,
- [In] DWMWINDOWATTRIBUTE dwAttributeToGet,
- [In] ref int pvAttributeValue,
- [In] int cbAttribute
- );
-
- ///
- /// Retrieves the current value of a specified Desktop Window Manager (DWM) attribute applied to a window. For programming guidance, and code examples, see Controlling non-client region rendering.
- ///
- /// The handle to the window from which the attribute value is to be retrieved.
- /// A flag describing which value to retrieve, specified as a value of the enumeration.
- /// A pointer to a value which, when this function returns successfully, receives the current value of the attribute. The type of the retrieved value depends on the value of the dwAttribute parameter.
- /// The size, in bytes, of the attribute value being received via the pvAttribute parameter.
- /// If the function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
- [DllImport(Libraries.Dwmapi)]
- public static extern int DwmGetWindowAttribute(
- [In] IntPtr hWnd,
- [In] int dwAttributeToGet,
- [In] ref int pvAttributeValue,
- [In] int cbAttribute
- );
-
- ///
- /// The feature is not included in the Microsoft documentation. Reads Desktop Window Manager (DWM) color information.
- ///
- /// A pointer to a reference value that will hold the color information.
- [DllImport(Libraries.Dwmapi, EntryPoint = "#127", PreserveSig = false, CharSet = CharSet.Unicode)]
- public static extern void DwmGetColorizationParameters([Out] out DWMCOLORIZATIONPARAMS dwParameters);
-}
-
-#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
diff --git a/src/Wpf.Ui/Interop/HRESULT.cs b/src/Wpf.Ui/Interop/HRESULT.cs
deleted file mode 100644
index 3d829dab2..000000000
--- a/src/Wpf.Ui/Interop/HRESULT.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop;
-
-///
-/// Common Windows API result;
-///
-internal struct HRESULT
-{
- ///
- /// Operation successful.
- ///
- public const int S_OK = unchecked((int)0x00000000);
-
- ///
- /// Operation successful.
- ///
- public const int NO_ERROR = unchecked((int)0x00000000);
-
- ///
- /// Operation successful.
- ///
- public const int NOERROR = unchecked((int)0x00000000);
-
- ///
- /// Unspecified failure.
- ///
- public const int S_FALSE = unchecked((int)0x00000001);
-
- public static void Check(int hr)
- {
- if (hr >= S_OK)
- {
- return;
- }
-
- Marshal.ThrowExceptionForHR(hr, (IntPtr)(-1));
- }
-}
diff --git a/src/Wpf.Ui/Interop/Kernel32.cs b/src/Wpf.Ui/Interop/Kernel32.cs
deleted file mode 100644
index d66562109..000000000
--- a/src/Wpf.Ui/Interop/Kernel32.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-// This Source Code is partially based on reverse engineering of the Windows Operating System,
-// and is intended for use on Windows systems only.
-// This Source Code is partially based on the source code provided by the .NET Foundation.
-//
-// NOTE:
-// I split unmanaged code stuff into the NativeMethods library.
-// If you have suggestions for the code below, please submit your changes there.
-// https://github.com/lepoco/nativemethods
-
-// ReSharper disable IdentifierTypo
-// ReSharper disable InconsistentNaming
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop;
-
-///
-/// Used by multiple technologies.
-///
-internal class Kernel32
-{
- ///
- /// Retrieves the calling thread's last-error code value. The last-error code is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error code.
- ///
- /// The return value is the calling thread's last-error code.
- [DllImport(Libraries.Kernel32)]
- public static extern int GetLastError();
-
- ///
- /// Sets the last-error code for the calling thread.
- ///
- /// The last-error code for the thread.
- [DllImport(Libraries.Kernel32, ExactSpelling = true, CharSet = CharSet.Auto)]
- public static extern void SetLastError([In] int dwErrorCode);
-
- ///
- /// Determines whether the calling process is being debugged by a user-mode debugger.
- ///
- /// If the current process is running in the context of a debugger, the return value is nonzero.
- [DllImport(Libraries.Kernel32, ExactSpelling = true, CharSet = CharSet.Auto)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool IsDebuggerPresent();
-}
diff --git a/src/Wpf.Ui/Interop/Libraries.cs b/src/Wpf.Ui/Interop/Libraries.cs
deleted file mode 100644
index f40e3613b..000000000
--- a/src/Wpf.Ui/Interop/Libraries.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-namespace Wpf.Ui.Interop;
-
-///
-/// Windows kernel module.
-///
-internal static class Libraries
-{
- /*internal const string Advapi32 = "advapi32.dll";
- internal const string BCrypt = "BCrypt.dll";
- internal const string CoreComm_L1_1_1 = "api-ms-win-core-comm-l1-1-1.dll";
- internal const string Crypt32 = "crypt32.dll";*/
- internal const string Dwmapi = "dwmapi.dll";
-
- /*internal const string Error_L1 = "api-ms-win-core-winrt-error-l1-1-0.dll";
- internal const string HttpApi = "httpapi.dll";
- internal const string IpHlpApi = "iphlpapi.dll";*/
- internal const string Kernel32 = "kernel32.dll";
-
- /*internal const string Memory_L1_3 = "api-ms-win-core-memory-l1-1-3.dll";
- internal const string Mswsock = "mswsock.dll";
- internal const string NCrypt = "ncrypt.dll";
- internal const string NtDll = "ntdll.dll";
- internal const string Odbc32 = "odbc32.dll";
- internal const string OleAut32 = "oleaut32.dll";
- internal const string PerfCounter = "perfcounter.dll";
- internal const string RoBuffer = "api-ms-win-core-winrt-robuffer-l1-1-0.dll";
- internal const string Secur32 = "secur32.dll";*/
- internal const string Shell32 = "shell32.dll";
-
- /*internal const string SspiCli = "sspicli.dll";*/
- internal const string User32 = "user32.dll";
- internal const string UxTheme = "uxtheme.dll";
-
- /*internal const string Gdi32 = "gdi32.dll";
- internal const string Gdip = "gdiplus.dll";*/
- internal const string Version = "version.dll";
- /*internal const string WebSocket = "websocket.dll";
- internal const string WinHttp = "winhttp.dll";
- internal const string WinMM = "winmm.dll";
- internal const string Ws2_32 = "ws2_32.dll";
- internal const string Wtsapi32 = "wtsapi32.dll";
- internal const string CompressionNative = "System.IO.Compression.Native.dll";*/
-}
diff --git a/src/Wpf.Ui/Interop/PInvoke.cs b/src/Wpf.Ui/Interop/PInvoke.cs
new file mode 100644
index 000000000..1d4c052c5
--- /dev/null
+++ b/src/Wpf.Ui/Interop/PInvoke.cs
@@ -0,0 +1,19 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Runtime.InteropServices;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.WindowsAndMessaging;
+
+namespace Windows.Win32;
+
+internal static partial class PInvoke
+{
+ [
+ DllImport("USER32.dll", ExactSpelling = true, EntryPoint = "SetWindowLongPtrW", SetLastError = true),
+ DefaultDllImportSearchPaths(DllImportSearchPath.System32)
+ ]
+ internal static extern nint SetWindowLongPtr(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, nint dwNewLong);
+}
diff --git a/src/Wpf.Ui/Interop/ShObjIdl.cs b/src/Wpf.Ui/Interop/ShObjIdl.cs
deleted file mode 100644
index cc334f43e..000000000
--- a/src/Wpf.Ui/Interop/ShObjIdl.cs
+++ /dev/null
@@ -1,240 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-// This Source Code is partially based on reverse engineering of the Windows Operating System,
-// and is intended for use on Windows systems only.
-// This Source Code is partially based on the source code provided by the .NET Foundation.
-//
-// NOTE:
-// I split unmanaged code stuff into the NativeMethods library.
-// If you have suggestions for the code below, please submit your changes there.
-// https://github.com/lepoco/nativemethods
-
-// ReSharper disable IdentifierTypo
-// ReSharper disable InconsistentNaming
-#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop;
-
-///
-/// Exposes methods that enumerate the contents of a view and receive notification from callback upon enumeration completion.
-///
-internal static class ShObjIdl
-{
- ///
- /// THUMBBUTTON flags. THBF_*
- ///
- [Flags]
- public enum THUMBBUTTONFLAGS
- {
- THBF_ENABLED = 0,
- THBF_DISABLED = 0x1,
- THBF_DISMISSONCLICK = 0x2,
- THBF_NOBACKGROUND = 0x4,
- THBF_HIDDEN = 0x8,
- THBF_NONINTERACTIVE = 0x10
- }
-
- ///
- /// THUMBBUTTON mask. THB_*
- ///
- [Flags]
- public enum THUMBBUTTONMASK
- {
- THB_BITMAP = 0x1,
- THB_ICON = 0x2,
- THB_TOOLTIP = 0x4,
- THB_FLAGS = 0x8
- }
-
- ///
- /// TBPF_*
- ///
- [Flags]
- public enum TBPFLAG
- {
- TBPF_NOPROGRESS = 0,
- TBPF_INDETERMINATE = 0x1,
- TBPF_NORMAL = 0x2,
- TBPF_ERROR = 0x4,
- TBPF_PAUSED = 0x8
- }
-
- ///
- /// STPF_*
- ///
- [Flags]
- public enum STPFLAG
- {
- STPF_NONE = 0,
- STPF_USEAPPTHUMBNAILALWAYS = 0x1,
- STPF_USEAPPTHUMBNAILWHENACTIVE = 0x2,
- STPF_USEAPPPEEKALWAYS = 0x4,
- STPF_USEAPPPEEKWHENACTIVE = 0x8
- }
-
- ///
- /// EBO_*
- ///
- public enum EXPLORER_BROWSER_OPTIONS
- {
- EBO_NONE = 0,
- EBO_NAVIGATEONCE = 0x1,
- EBO_SHOWFRAMES = 0x2,
- EBO_ALWAYSNAVIGATE = 0x4,
- EBO_NOTRAVELLOG = 0x8,
- EBO_NOWRAPPERWINDOW = 0x10,
- EBO_HTMLSHAREPOINTVIEW = 0x20,
- EBO_NOBORDER = 0x40,
- EBO_NOPERSISTVIEWSTATE = 0x80
- }
-
- ///
- /// EBF_*
- ///
- public enum EXPLORER_BROWSER_FILL_FLAGS
- {
- EBF_NONE = 0,
- EBF_SELECTFROMDATAOBJECT = 0x100,
- EBF_NODROPTARGET = 0x200
- }
-
- ///
- /// THUMBBUTTON
- ///
- [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]
- public struct THUMBBUTTON
- {
- ///
- /// WPARAM value for a THUMBBUTTON being clicked.
- ///
- public const int THBN_CLICKED = 0x1800;
-
- public THUMBBUTTONMASK dwMask;
- public uint iId;
- public uint iBitmap;
- public IntPtr hIcon;
-
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
- public string szTip;
-
- public THUMBBUTTONFLAGS dwFlags;
- }
-
- ///
- /// Class DECLSPEC_UUID("56FDF344-FD6D-11d0-958A-006097C9A090")
- ///
- [Guid("56FDF344-FD6D-11d0-958A-006097C9A090")]
- [ClassInterface(ClassInterfaceType.None)]
- [ComImport]
- public class CTaskbarList { }
-
- ///
- /// Class DECLSPEC_UUID("9ac9fbe1-e0a2-4ad6-b4ee-e212013ea917")
- ///
- [Guid("9ac9fbe1-e0a2-4ad6-b4ee-e212013ea917")]
- [ClassInterface(ClassInterfaceType.None)]
- [ComImport]
- public class ShellItem { }
-
- ///
- /// MIDL_INTERFACE("c43dc798-95d1-4bea-9030-bb99e2983a1a")
- /// ITaskbarList4 : public ITaskbarList3
- ///
- [ComImport]
- [Guid("c43dc798-95d1-4bea-9030-bb99e2983a1a")]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface ITaskbarList4
- {
- // ITaskbarList
- [PreserveSig]
- void HrInit();
-
- [PreserveSig]
- void AddTab(IntPtr hwnd);
-
- [PreserveSig]
- void DeleteTab(IntPtr hwnd);
-
- [PreserveSig]
- void ActivateTab(IntPtr hwnd);
-
- [PreserveSig]
- void SetActiveAlt(IntPtr hwnd);
-
- // ITaskbarList2
- [PreserveSig]
- void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
-
- // ITaskbarList3
- [PreserveSig]
- void SetProgressValue(IntPtr hwnd, ulong ullCompleted, ulong ullTotal);
-
- [PreserveSig]
- void SetProgressState(IntPtr hwnd, TBPFLAG tbpFlags);
-
- [PreserveSig]
- void RegisterTab(IntPtr hwndTab, IntPtr hwndMDI);
-
- [PreserveSig]
- void UnregisterTab(IntPtr hwndTab);
-
- [PreserveSig]
- void SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore);
-
- [PreserveSig]
- void SetTabActive(IntPtr hwndTab, IntPtr hwndInsertBefore, uint dwReserved);
-
- ///
- /// Adds thumbnail toolbar buttons to the specified window.
- ///
- /// Window handle.
- /// Number of buttons.
- /// Array of buttons.
- /// HRESULT
- [PreserveSig]
- int ThumbBarAddButtons(
- IntPtr hwnd,
- uint cButtons,
- [MarshalAs(UnmanagedType.LPArray)] THUMBBUTTON[] pButtons
- );
-
- ///
- /// Updates thumbnail toolbar buttons for the specified window.
- ///
- /// Window handle.
- /// Number of buttons.
- /// Array of buttons to update.
- /// HRESULT
- [PreserveSig]
- int ThumbBarUpdateButtons(
- IntPtr hwnd,
- uint cButtons,
- [MarshalAs(UnmanagedType.LPArray)] THUMBBUTTON[] pButtons
- );
-
- [PreserveSig]
- void ThumbBarSetImageList(IntPtr hWnd, IntPtr himl);
-
- [PreserveSig]
- void SetOverlayIcon(
- IntPtr hwnd,
- IntPtr hIcon,
- [MarshalAs(UnmanagedType.LPWStr)] string pszDescription
- );
-
- [PreserveSig]
- void SetThumbnailTooltip(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszTip);
-
- [PreserveSig]
- void SetThumbnailClip(IntPtr hwnd, IntPtr prcClip);
-
- // ITaskbarList4
- void SetTabProperties(IntPtr hwndTab, STPFLAG stpFlags);
- }
-}
-
-#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
diff --git a/src/Wpf.Ui/Interop/Shell32.cs b/src/Wpf.Ui/Interop/Shell32.cs
deleted file mode 100644
index 9b1a4de70..000000000
--- a/src/Wpf.Ui/Interop/Shell32.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-// This Source Code is partially based on reverse engineering of the Windows Operating System,
-// and is intended for use on Windows systems only.
-// This Source Code is partially based on the source code provided by the .NET Foundation.
-//
-// NOTE:
-// I split unmanaged code stuff into the NativeMethods library.
-// If you have suggestions for the code below, please submit your changes there.
-// https://github.com/lepoco/nativemethods
-
-// ReSharper disable IdentifierTypo
-// ReSharper disable InconsistentNaming
-#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
-#pragma warning disable SA1401 // Fields should be private
-
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.ComTypes;
-
-namespace Wpf.Ui.Interop;
-
-///
-/// The Windows UI provides users with access to a wide variety of objects necessary to run applications and manage the operating system.
-///
-internal static class Shell32
-{
- ///
- /// DATAOBJ_GET_ITEM_FLAGS. DOGIF_*.
- ///
- public enum DOGIF
- {
- DEFAULT = 0x0000,
- TRAVERSE_LINK = 0x0001, // if the item is a link get the target
- NO_HDROP = 0x0002, // don't fallback and use CF_HDROP clipboard format
- NO_URL = 0x0004, // don't fallback and use URL clipboard format
- ONLY_IF_ONE = 0x0008, // only return the item if there is one item in the array
- }
-
- ///
- /// Shell_NotifyIcon messages. NIM_*
- ///
- public enum NIM : uint
- {
- ADD = 0,
- MODIFY = 1,
- DELETE = 2,
- SETFOCUS = 3,
- SETVERSION = 4,
- }
-
- ///
- /// Shell_NotifyIcon flags. NIF_*
- ///
- [Flags]
- public enum NIF : uint
- {
- MESSAGE = 0x0001,
- ICON = 0x0002,
- TIP = 0x0004,
- STATE = 0x0008,
- INFO = 0x0010,
- GUID = 0x0020,
-
- ///
- /// Vista only.
- ///
- REALTIME = 0x0040,
-
- ///
- /// Vista only.
- ///
- SHOWTIP = 0x0080,
-
- XP_MASK = MESSAGE | ICON | STATE | INFO | GUID,
- VISTA_MASK = XP_MASK | REALTIME | SHOWTIP,
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public class NOTIFYICONDATA
- {
- ///
- /// The size of this structure, in bytes.
- ///
- public int cbSize = Marshal.SizeOf(typeof(NOTIFYICONDATA));
-
- ///
- /// A handle to the window that receives notifications associated with an icon in the notification area.
- ///
- public IntPtr hWnd;
-
- ///
- /// The application-defined identifier of the taskbar icon. The Shell uses either (hWnd plus uID) or guidItem to identify which icon to operate on when Shell_NotifyIcon is invoked.
- /// You can have multiple icons associated with a single hWnd by assigning each a different uID. If guidItem is specified, uID is ignored.
- ///
- public int uID;
-
- ///
- /// Flags that either indicate which of the other members of the structure contain valid data or provide additional information to the tooltip as to how it should display.
- ///
- public NIF uFlags;
-
- ///
- /// 0x00000001. The uCallbackMessage member is valid.
- ///
- public int uCallbackMessage;
-
- ///
- /// 0x00000002. The hIcon member is valid.
- ///
- public IntPtr hIcon;
-
- ///
- /// 0x00000004. The szTip member is valid.
- ///
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x80)] // 128
- public string? szTip;
-
- ///
- /// The state of the icon. There are two flags that can be set independently.
- /// NIS_HIDDEN = 1. The icon is hidden.
- /// NIS_SHAREDICON = 2. The icon is shared.
- ///
- public uint dwState;
-
- public uint dwStateMask;
-
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x100)] // 256
- public string? szInfo;
-
- ///
- /// Prior to Vista this was a union of uTimeout and uVersion. As of Vista, uTimeout has been deprecated.
- ///
- public uint uVersion; // Used with Shell_NotifyIcon flag NIM_SETVERSION.
-
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x40)] // 64
- public string? szInfoTitle;
-
- public uint dwInfoFlags;
-
- public Guid guidItem;
-
- // Vista only
- public IntPtr hBalloonIcon;
- }
-
- [DllImport(Libraries.Shell32, PreserveSig = false)]
- public static extern void SHGetItemFromDataObject(
- System.Runtime.InteropServices.ComTypes.IDataObject pdtobj,
- DOGIF dwFlags,
- [In] ref Guid riid,
- [Out, MarshalAs(UnmanagedType.Interface)] out object ppv
- );
-
- [DllImport(Libraries.Shell32)]
- public static extern int SHCreateItemFromParsingName(
- [MarshalAs(UnmanagedType.LPWStr)] string pszPath,
- IBindCtx pbc,
- [In] ref Guid riid,
- [Out, MarshalAs(UnmanagedType.Interface)] out object ppv
- );
-
- [DllImport(Libraries.Shell32)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool Shell_NotifyIcon([In] NIM dwMessage, [In] NOTIFYICONDATA lpdata);
-
- ///
- /// Sets the User Model AppID for the current process, enabling Windows to retrieve this ID
- ///
- /// The string ID
- [DllImport(Libraries.Shell32, PreserveSig = false)]
- public static extern void SetCurrentProcessExplicitAppUserModelID(
- [MarshalAs(UnmanagedType.LPWStr)] string AppID
- );
-
- ///
- /// Retrieves the User Model AppID that has been explicitly set for the current process via SetCurrentProcessExplicitAppUserModelID
- ///
- /// The returned string ID of the Application User Model.
- /// An HRESULT indicating success or failure of the operation.
- [DllImport(Libraries.Shell32)]
- public static extern int GetCurrentProcessExplicitAppUserModelID(
- [Out, MarshalAs(UnmanagedType.LPWStr)] out string AppID
- );
-}
-
-#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
-#pragma warning restore SA1401 // Fields should be private
diff --git a/src/Wpf.Ui/Interop/UnsafeNativeMethods.cs b/src/Wpf.Ui/Interop/UnsafeNativeMethods.cs
index e73401cca..067e3ef5b 100644
--- a/src/Wpf.Ui/Interop/UnsafeNativeMethods.cs
+++ b/src/Wpf.Ui/Interop/UnsafeNativeMethods.cs
@@ -7,57 +7,129 @@
and is intended for use on Windows systems only.
This Source Code is partially based on the source code provided by the .NET Foundation. */
-using System.Runtime.InteropServices;
using Microsoft.Win32;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.Graphics.Dwm;
+using Windows.Win32.UI.Controls;
+using Windows.Win32.UI.Shell;
+using Windows.Win32.UI.WindowsAndMessaging;
using Wpf.Ui.Controls;
-using Wpf.Ui.Hardware;
namespace Wpf.Ui.Interop;
///
/// A set of dangerous methods to modify the appearance.
///
-public static class UnsafeNativeMethods
+internal static class UnsafeNativeMethods
{
///
- /// Tries to set the corner preference.
+ /// Tries to set the corner preference of the selected window.
///
- /// Selected window.
+ /// Selected window handle.
/// Window corner preference.
/// if invocation of native Windows function succeeds.
- public static bool ApplyWindowCornerPreference(Window window, WindowCornerPreference cornerPreference) =>
- GetHandle(window, out IntPtr windowHandle)
- && ApplyWindowCornerPreference(windowHandle, cornerPreference);
+ public static unsafe bool ApplyWindowCornerPreference(
+ IntPtr handle,
+ WindowCornerPreference cornerPreference
+ )
+ {
+ if (handle == IntPtr.Zero)
+ {
+ return false;
+ }
+
+ if (!PInvoke.IsWindow(new HWND(handle)))
+ {
+ return false;
+ }
+
+ DWM_WINDOW_CORNER_PREFERENCE pvAttribute = UnsafeReflection.Cast(cornerPreference);
+
+ return PInvoke.DwmSetWindowAttribute(
+ new HWND(handle),
+ DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE,
+ &pvAttribute,
+ sizeof(int)
+ ) == HRESULT.S_OK;
+ }
///
- /// Tries to set the corner preference of the selected window.
+ /// Tries to apply the color of the border.
///
- /// Selected window handle.
- /// Window corner preference.
+ /// The window.
+ /// The color.
+ /// if invocation of native Windows function succeeds.
+ public static bool ApplyBorderColor(Window window, Color color) =>
+ GetHandle(window, out IntPtr windowHandle) && ApplyBorderColor(windowHandle, color);
+
+ ///
+ /// Tries to apply the color of the border.
+ ///
+ /// The window.
+ /// The color.
+ /// if invocation of native Windows function succeeds.
+ public static bool ApplyBorderColor(Window window, int color) =>
+ GetHandle(window, out IntPtr windowHandle) && ApplyBorderColor(windowHandle, color);
+
+ ///
+ /// Tries to apply the color of the border.
+ ///
+ /// The handle.
+ /// The color.
+ /// if invocation of native Windows function succeeds.
+ public static bool ApplyBorderColor(IntPtr handle, Color color)
+ {
+ return ApplyBorderColor(handle, (color.B << 16) | (color.G << 8) | color.R);
+ }
+
+ ///
+ /// Tries to apply the color of the border.
+ ///
+ /// The handle.
+ /// The color.
/// if invocation of native Windows function succeeds.
- public static bool ApplyWindowCornerPreference(IntPtr handle, WindowCornerPreference cornerPreference)
+ public static unsafe bool ApplyBorderColor(IntPtr handle, int color)
{
if (handle == IntPtr.Zero)
{
return false;
}
- if (!User32.IsWindow(handle))
+ if (!PInvoke.IsWindow(new HWND(handle)))
{
return false;
}
- int pvAttribute = (int)UnsafeReflection.Cast(cornerPreference);
+ return PInvoke.DwmSetWindowAttribute(
+ new HWND(handle),
+ DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR,
+ &color,
+ sizeof(int)
+ ) == HRESULT.S_OK;
+ }
- // TODO: Validate HRESULT
- _ = Dwmapi.DwmSetWindowAttribute(
- handle,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE,
- ref pvAttribute,
- Marshal.SizeOf(typeof(int))
- );
+ ///
+ /// Checks whether accent color on title bars and window borders is enabled in Windows settings.
+ ///
+ /// if accent color on title bars is enabled.
+ public static bool IsAccentColorOnTitleBarsEnabled()
+ {
+ try
+ {
+ using RegistryKey? key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\DWM");
- return true;
+ if (key?.GetValue("ColorPrevalence") is int value)
+ {
+ return value == 1;
+ }
+ }
+ catch
+ {
+ // Ignore registry access errors
+ }
+
+ return false;
}
///
@@ -73,30 +145,28 @@ public static bool RemoveWindowDarkMode(Window? window) =>
///
/// Window handle.
/// if invocation of native Windows function succeeds.
- public static bool RemoveWindowDarkMode(IntPtr handle)
+ public static unsafe bool RemoveWindowDarkMode(IntPtr handle)
{
if (handle == IntPtr.Zero)
{
return false;
}
- if (!User32.IsWindow(handle))
+ if (!PInvoke.IsWindow(new HWND(handle)))
{
return false;
}
- var pvAttribute = 0x0; // Disable
- Dwmapi.DWMWINDOWATTRIBUTE dwAttribute = Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE;
+ BOOL pvAttribute = false;
+ DWMWINDOWATTRIBUTE dwAttribute = DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE;
if (!Win32.Utilities.IsOSWindows11Insider1OrNewer)
{
- dwAttribute = Dwmapi.DWMWINDOWATTRIBUTE.DMWA_USE_IMMERSIVE_DARK_MODE_OLD;
+ dwAttribute = DWMWINDOWATTRIBUTE.DMWA_USE_IMMERSIVE_DARK_MODE_OLD;
}
- // TODO: Validate HRESULT
- _ = Dwmapi.DwmSetWindowAttribute(handle, dwAttribute, ref pvAttribute, Marshal.SizeOf(typeof(int)));
-
- return true;
+ return PInvoke.DwmSetWindowAttribute(new HWND(handle), dwAttribute, &pvAttribute, (uint)sizeof(BOOL))
+ == HRESULT.S_OK;
}
///
@@ -112,30 +182,28 @@ public static bool ApplyWindowDarkMode(Window? window) =>
///
/// Window handle.
/// if invocation of native Windows function succeeds.
- public static bool ApplyWindowDarkMode(IntPtr handle)
+ public static unsafe bool ApplyWindowDarkMode(IntPtr handle)
{
if (handle == IntPtr.Zero)
{
return false;
}
- if (!User32.IsWindow(handle))
+ if (!PInvoke.IsWindow(new HWND(handle)))
{
return false;
}
- var pvAttribute = 0x1; // Enable
- Dwmapi.DWMWINDOWATTRIBUTE dwAttribute = Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE;
+ BOOL pvAttribute = true;
+ DWMWINDOWATTRIBUTE dwAttribute = DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE;
if (!Win32.Utilities.IsOSWindows11Insider1OrNewer)
{
- dwAttribute = Dwmapi.DWMWINDOWATTRIBUTE.DMWA_USE_IMMERSIVE_DARK_MODE_OLD;
+ dwAttribute = DWMWINDOWATTRIBUTE.DMWA_USE_IMMERSIVE_DARK_MODE_OLD;
}
- // TODO: Validate HRESULT
- _ = Dwmapi.DwmSetWindowAttribute(handle, dwAttribute, ref pvAttribute, Marshal.SizeOf(typeof(int)));
-
- return true;
+ return PInvoke.DwmSetWindowAttribute(new HWND(handle), dwAttribute, &pvAttribute, (uint)sizeof(BOOL))
+ == HRESULT.S_OK;
}
///
@@ -176,211 +244,48 @@ public static bool RemoveWindowTitlebarContents(IntPtr handle)
return false;
}
- if (!User32.IsWindow(handle))
+ if (!PInvoke.IsWindow(new HWND(handle)))
{
return false;
}
- var windowStyleLong = User32.GetWindowLong(handle, User32.GWL.GWL_STYLE);
- windowStyleLong &= ~(int)User32.WS.SYSMENU;
+ var windowStyleLong = PInvoke.GetWindowLong(new HWND(handle), WINDOW_LONG_PTR_INDEX.GWL_STYLE);
+ windowStyleLong &= ~(int)WINDOW_STYLE.WS_SYSMENU;
- IntPtr result = SetWindowLong(handle, User32.GWL.GWL_STYLE, windowStyleLong);
+ IntPtr result = SetWindowLong(handle, WINDOW_LONG_PTR_INDEX.GWL_STYLE, windowStyleLong);
- return result.ToInt64() > 0x0;
- }
-
- ///
- /// Tries to apply selected backdrop type for window handle.
- ///
- /// Selected window handle.
- /// Backdrop type.
- /// if invocation of native Windows function succeeds.
- public static bool ApplyWindowBackdrop(IntPtr handle, WindowBackdropType backgroundType)
- {
- if (handle == IntPtr.Zero)
- {
- return false;
- }
-
- if (!User32.IsWindow(handle))
- {
- return false;
- }
-
- var backdropPvAttribute = (int)UnsafeReflection.Cast(backgroundType);
-
- if (backdropPvAttribute == (int)Dwmapi.DWMSBT.DWMSBT_DISABLE)
- {
- return false;
- }
-
- // TODO: Validate HRESULT
- _ = Dwmapi.DwmSetWindowAttribute(
- handle,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
- ref backdropPvAttribute,
- Marshal.SizeOf(typeof(int))
- );
-
- return true;
- }
-
- ///
- /// Tries to determine whether the provided has applied legacy backdrop effect.
- ///
- /// Window handle.
- /// Background backdrop type.
- public static bool IsWindowHasBackdrop(IntPtr handle, WindowBackdropType backdropType)
- {
- if (!User32.IsWindow(handle))
- {
- return false;
- }
-
- var pvAttribute = 0x0;
-
- _ = Dwmapi.DwmGetWindowAttribute(
- handle,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
- ref pvAttribute,
- Marshal.SizeOf(typeof(int))
- );
-
- return pvAttribute == (int)UnsafeReflection.Cast(backdropType);
- }
-
- ///
- /// Tries to determine whether the provided has applied legacy Mica effect.
- ///
- /// Window to check.
- public static bool IsWindowHasLegacyMica(Window? window) =>
- GetHandle(window, out IntPtr windowHandle) && IsWindowHasLegacyMica(windowHandle);
-
- ///
- /// Tries to determine whether the provided handle has applied legacy Mica effect.
- ///
- /// Window handle.
- public static bool IsWindowHasLegacyMica(IntPtr handle)
- {
- if (!User32.IsWindow(handle))
- {
- return false;
- }
-
- var pvAttribute = 0x0;
-
- _ = Dwmapi.DwmGetWindowAttribute(
- handle,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_MICA_EFFECT,
- ref pvAttribute,
- Marshal.SizeOf(typeof(int))
- );
-
- return pvAttribute == 0x1;
- }
-
- ///
- /// Tries to apply legacy Mica effect for the selected .
- ///
- /// The window to which the effect is to be applied.
- /// if invocation of native Windows function succeeds.
- public static bool ApplyWindowLegacyMicaEffect(Window? window) =>
- GetHandle(window, out IntPtr windowHandle) && ApplyWindowLegacyMicaEffect(windowHandle);
-
- ///
- /// Tries to apply legacy Mica effect for the selected .
- ///
- /// Window handle.
- /// if invocation of native Windows function succeeds.
- public static bool ApplyWindowLegacyMicaEffect(IntPtr handle)
- {
- var backdropPvAttribute = 0x1; // Enable
-
- // TODO: Validate HRESULT
- _ = Dwmapi.DwmSetWindowAttribute(
- handle,
- Dwmapi.DWMWINDOWATTRIBUTE.DWMWA_MICA_EFFECT,
- ref backdropPvAttribute,
- Marshal.SizeOf(typeof(int))
- );
-
- return true;
- }
-
- ///
- /// Tries to apply legacy Acrylic effect for the selected .
- ///
- /// The window to which the effect is to be applied.
- /// if invocation of native Windows function succeeds.
- public static bool ApplyWindowLegacyAcrylicEffect(Window? window) =>
- GetHandle(window, out IntPtr windowHandle) && ApplyWindowLegacyAcrylicEffect(windowHandle);
-
- ///
- /// Tries to apply legacy Acrylic effect for the selected .
- ///
- /// Window handle
- /// if invocation of native Windows function succeeds.
- public static bool ApplyWindowLegacyAcrylicEffect(IntPtr handle)
- {
- var accentPolicy = new Interop.User32.ACCENT_POLICY
- {
- nAccentState = User32.ACCENT_STATE.ACCENT_ENABLE_ACRYLICBLURBEHIND,
- nColor = 0x990000 & 0xFFFFFF
- };
-
- int accentStructSize = Marshal.SizeOf(accentPolicy);
- IntPtr accentPtr = Marshal.AllocHGlobal(accentStructSize);
-
- Marshal.StructureToPtr(accentPolicy, accentPtr, false);
-
- var data = new User32.WINCOMPATTRDATA
- {
- Attribute = User32.WCA.WCA_ACCENT_POLICY,
- SizeOfData = accentStructSize,
- Data = accentPtr
- };
-
- _ = User32.SetWindowCompositionAttribute(handle, ref data);
-
- Marshal.FreeHGlobal(accentPtr);
-
- return true;
+ return result.ToInt64() > 0;
}
///
/// Tries to get currently selected Window accent color.
///
- public static Color GetDwmColor()
+ public static Color GetAccentColor()
{
try
{
- Dwmapi.DwmGetColorizationParameters(out Dwmapi.DWMCOLORIZATIONPARAMS dwmParams);
- var values = BitConverter.GetBytes(dwmParams.clrColor);
-
- return Color.FromArgb(255, values[2], values[1], values[0]);
- }
- catch
- {
- var colorizationColorValue = Registry.GetValue(
+ var accentColorValue = Registry.GetValue(
@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM",
- "ColorizationColor",
+ "AccentColor",
null
);
- if (colorizationColorValue is not null)
+ if (accentColorValue is not null)
{
- try
- {
- var colorizationColor = (uint)(int)colorizationColorValue;
- var values = BitConverter.GetBytes(colorizationColor);
-
- return Color.FromArgb(255, values[2], values[1], values[0]);
- }
- catch { }
+ var accentColor = (uint)(int)accentColorValue;
+ var values = BitConverter.GetBytes(accentColor);
+
+ return Color.FromArgb(255, values[0], values[1], values[2]);
}
}
+ catch
+ {
+ // Ignored.
+ }
- return GetDefaultWindowsAccentColor();
+ // Windows default accent color
+ // https://learn.microsoft.com/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-themes-windowcolor#values
+ return Color.FromArgb(0xff, 0x00, 0x78, 0xd7);
}
///
@@ -388,25 +293,25 @@ public static Color GetDwmColor()
///
/// Window handle.
/// Taskbar flag.
- internal static bool SetTaskbarState(IntPtr hWnd, ShObjIdl.TBPFLAG taskbarFlag)
+ internal static bool SetTaskbarState(IntPtr hWnd, TBPFLAG taskbarFlag)
{
if (hWnd == IntPtr.Zero)
{
return false;
}
- if (!User32.IsWindow(hWnd))
+ if (!PInvoke.IsWindow(new HWND(hWnd)))
{
return false;
}
- if (new ShObjIdl.CTaskbarList() is not ShObjIdl.ITaskbarList4 taskbarList)
+ if (new TaskbarList() is not ITaskbarList4 taskbarList)
{
return false;
}
taskbarList.HrInit();
- taskbarList.SetProgressState(hWnd, taskbarFlag);
+ taskbarList.SetProgressState(new HWND(hWnd), taskbarFlag);
return true;
}
@@ -419,154 +324,64 @@ internal static bool SetTaskbarState(IntPtr hWnd, ShObjIdl.TBPFLAG taskbarFlag)
/// Current progress value.
/// Maximum progress value.
/// True if successful updated, otherwise false.
- internal static bool SetTaskbarValue(IntPtr hWnd, ShObjIdl.TBPFLAG taskbarFlag, int current, int total)
+ internal static bool SetTaskbarValue(IntPtr hWnd, TBPFLAG taskbarFlag, int current, int total)
{
if (hWnd == IntPtr.Zero)
{
return false;
}
- if (!User32.IsWindow(hWnd))
+ if (!PInvoke.IsWindow(new HWND(hWnd)))
{
return false;
}
/* TODO: Get existing taskbar class */
- if (new ShObjIdl.CTaskbarList() is not ShObjIdl.ITaskbarList4 taskbarList)
+ if (new TaskbarList() is not ITaskbarList4 taskbarList)
{
return false;
}
taskbarList.HrInit();
- taskbarList.SetProgressState(hWnd, taskbarFlag);
-
- if (taskbarFlag is not ShObjIdl.TBPFLAG.TBPF_INDETERMINATE and not ShObjIdl.TBPFLAG.TBPF_NOPROGRESS)
- {
- taskbarList.SetProgressValue(hWnd, Convert.ToUInt64(current), Convert.ToUInt64(total));
- }
-
- return true;
- }
-
- public static bool RemoveWindowCaption(Window window)
- {
- if (window is null)
- {
- return false;
- }
-
- IntPtr windowHandle = new WindowInteropHelper(window).Handle;
+ taskbarList.SetProgressState(new HWND(hWnd), taskbarFlag);
- return RemoveWindowCaption(windowHandle);
- }
-
- public static bool RemoveWindowCaption(IntPtr hWnd)
- {
- if (hWnd == IntPtr.Zero)
- {
- return false;
- }
-
- if (!User32.IsWindow(hWnd))
+ if (taskbarFlag is not TBPFLAG.TBPF_INDETERMINATE and not TBPFLAG.TBPF_NOPROGRESS)
{
- return false;
+ taskbarList.SetProgressValue(new HWND(hWnd), Convert.ToUInt64(current), Convert.ToUInt64(total));
}
- var wtaOptions = new UxTheme.WTA_OPTIONS()
- {
- dwFlags = UxTheme.WTNCA.NODRAWCAPTION,
- dwMask = UxTheme.WTNCA.VALIDBITS
- };
-
- UxTheme.SetWindowThemeAttribute(
- hWnd,
- UxTheme.WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT,
- ref wtaOptions,
- (uint)Marshal.SizeOf(typeof(UxTheme.WTA_OPTIONS))
- );
-
return true;
}
- public static bool ExtendClientAreaIntoTitleBar(Window window)
- {
- if (window is null)
- {
- return false;
- }
-
- IntPtr windowHandle = new WindowInteropHelper(window).Handle;
-
- return ExtendClientAreaIntoTitleBar(windowHandle);
- }
-
- public static bool ExtendClientAreaIntoTitleBar(IntPtr hWnd)
+ public static unsafe bool RemoveWindowCaption(IntPtr hWnd)
{
- /*
- * !! EXPERIMENTAl !!
- * NOTE: WinRt has ExtendContentIntoTitlebar, but it needs some digging
- */
-
if (hWnd == IntPtr.Zero)
{
return false;
}
- if (!User32.IsWindow(hWnd))
+ if (!PInvoke.IsWindow(new HWND(hWnd)))
{
return false;
}
- // #1 Remove titlebar elements
- var wtaOptions = new UxTheme.WTA_OPTIONS()
- {
- dwFlags = UxTheme.WTNCA.NODRAWCAPTION | UxTheme.WTNCA.NODRAWICON | UxTheme.WTNCA.NOSYSMENU,
- dwMask = UxTheme.WTNCA.VALIDBITS
- };
-
- Interop.UxTheme.SetWindowThemeAttribute(
- hWnd,
- UxTheme.WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT,
- ref wtaOptions,
- (uint)Marshal.SizeOf(typeof(UxTheme.WTA_OPTIONS))
- );
-
- DisplayDpi windowDpi = DpiHelper.GetWindowDpi(hWnd);
-
- // #2 Extend glass frame
- Thickness deviceGlassThickness = DpiHelper.LogicalThicknessToDevice(
- new Thickness(-1, -1, -1, -1),
- windowDpi.DpiScaleX,
- windowDpi.DpiScaleY
- );
-
- var dwmMargin = new UxTheme.MARGINS
+ var wtaOptions = new WTA_OPTIONS()
{
- // err on the side of pushing in glass an extra pixel.
- cxLeftWidth = (int)Math.Ceiling(deviceGlassThickness.Left),
- cxRightWidth = (int)Math.Ceiling(deviceGlassThickness.Right),
- cyTopHeight = (int)Math.Ceiling(deviceGlassThickness.Top),
- cyBottomHeight = (int)Math.Ceiling(deviceGlassThickness.Bottom),
+ dwFlags = PInvoke.WTNCA_NODRAWCAPTION,
+ dwMask =
+ PInvoke.WTNCA_NODRAWCAPTION
+ | PInvoke.WTNCA_NODRAWICON
+ | PInvoke.WTNCA_NOMIRRORHELP
+ | PInvoke.WTNCA_NOSYSMENU,
};
- // #3 Extend client area
- Interop.Dwmapi.DwmExtendFrameIntoClientArea(hWnd, ref dwmMargin);
-
- // #4 Clear rounding region
- Interop.User32.SetWindowRgn(hWnd, IntPtr.Zero, Interop.User32.IsWindowVisible(hWnd));
-
- return true;
- }
-
- ///
- /// Checks whether the DWM composition is enabled.
- ///
- public static bool IsCompositionEnabled()
- {
- _ = Dwmapi.DwmIsCompositionEnabled(out var isEnabled);
-
- return isEnabled == 0x1;
+ return PInvoke.SetWindowThemeAttribute(
+ new HWND(hWnd),
+ WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT,
+ &wtaOptions,
+ (uint)sizeof(WTA_OPTIONS)
+ ) == HRESULT.S_OK;
}
///
@@ -574,7 +389,7 @@ public static bool IsCompositionEnabled()
///
public static bool IsValidWindow(IntPtr hWnd)
{
- return User32.IsWindow(hWnd);
+ return PInvoke.IsWindow(new HWND(hWnd));
}
///
@@ -595,20 +410,10 @@ private static bool GetHandle(Window? window, out IntPtr windowHandle)
return windowHandle != IntPtr.Zero;
}
- private static IntPtr SetWindowLong(IntPtr handle, User32.GWL nIndex, long windowStyleLong)
- {
- if (IntPtr.Size == 4)
- {
- return new IntPtr(User32.SetWindowLong(handle, (int)nIndex, (int)windowStyleLong));
- }
-
- return User32.SetWindowLongPtr(handle, (int)nIndex, checked((IntPtr)windowStyleLong));
- }
-
- private static Color GetDefaultWindowsAccentColor()
+ private static IntPtr SetWindowLong(IntPtr handle, WINDOW_LONG_PTR_INDEX nIndex, long windowStyleLong)
{
- // Windows default accent color
- // https://learn.microsoft.com/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-themes-windowcolor#values
- return Color.FromArgb(0xff, 0x00, 0x78, 0xd7);
+ return IntPtr.Size == 4
+ ? new IntPtr(PInvoke.SetWindowLong(new HWND(handle), nIndex, (int)windowStyleLong))
+ : PInvoke.SetWindowLongPtr(new HWND(handle), nIndex, (nint)windowStyleLong);
}
}
diff --git a/src/Wpf.Ui/Interop/UnsafeReflection.cs b/src/Wpf.Ui/Interop/UnsafeReflection.cs
index cb9ff3b05..068f2f7ad 100644
--- a/src/Wpf.Ui/Interop/UnsafeReflection.cs
+++ b/src/Wpf.Ui/Interop/UnsafeReflection.cs
@@ -7,6 +7,8 @@
and is intended for use on Windows systems only.
This Source Code is partially based on the source code provided by the .NET Foundation. */
+using Windows.Win32.Graphics.Dwm;
+using Windows.Win32.UI.Shell;
using Wpf.Ui.Controls;
using Wpf.Ui.TaskBar;
@@ -18,61 +20,31 @@ namespace Wpf.Ui.Interop;
internal static class UnsafeReflection
{
///
- /// Casts to .
+ /// Casts to .
///
- public static Dwmapi.DWMSBT Cast(WindowBackdropType backgroundType)
- {
- return backgroundType switch
- {
- WindowBackdropType.Auto => Dwmapi.DWMSBT.DWMSBT_AUTO,
- WindowBackdropType.Mica => Dwmapi.DWMSBT.DWMSBT_MAINWINDOW,
- WindowBackdropType.Acrylic => Dwmapi.DWMSBT.DWMSBT_TRANSIENTWINDOW,
- WindowBackdropType.Tabbed => Dwmapi.DWMSBT.DWMSBT_TABBEDWINDOW,
- _ => Dwmapi.DWMSBT.DWMSBT_DISABLE
- };
- }
-
- ///
- /// Casts to .
- ///
- public static Dwmapi.DWM_WINDOW_CORNER_PREFERENCE Cast(WindowCornerPreference cornerPreference)
+ public static DWM_WINDOW_CORNER_PREFERENCE Cast(WindowCornerPreference cornerPreference)
{
return cornerPreference switch
{
- WindowCornerPreference.Round => Dwmapi.DWM_WINDOW_CORNER_PREFERENCE.ROUND,
- WindowCornerPreference.RoundSmall => Dwmapi.DWM_WINDOW_CORNER_PREFERENCE.ROUNDSMALL,
- WindowCornerPreference.DoNotRound => Dwmapi.DWM_WINDOW_CORNER_PREFERENCE.DONOTROUND,
- _ => Dwmapi.DWM_WINDOW_CORNER_PREFERENCE.DEFAULT
+ WindowCornerPreference.Round => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND,
+ WindowCornerPreference.RoundSmall => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUNDSMALL,
+ WindowCornerPreference.DoNotRound => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DONOTROUND,
+ _ => DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DEFAULT,
};
}
///
- /// Casts to .
+ /// Casts to .
///
- public static ShObjIdl.TBPFLAG Cast(TaskBarProgressState taskBarProgressState)
+ public static TBPFLAG Cast(TaskBarProgressState taskBarProgressState)
{
return taskBarProgressState switch
{
- TaskBarProgressState.Indeterminate => ShObjIdl.TBPFLAG.TBPF_INDETERMINATE,
- TaskBarProgressState.Error => ShObjIdl.TBPFLAG.TBPF_ERROR,
- TaskBarProgressState.Paused => ShObjIdl.TBPFLAG.TBPF_PAUSED,
- TaskBarProgressState.Normal => ShObjIdl.TBPFLAG.TBPF_NORMAL,
- _ => Wpf.Ui.Interop.ShObjIdl.TBPFLAG.TBPF_NOPROGRESS
- };
- }
-
- ///
- /// Casts to .
- ///
- public static TaskBarProgressState Cast(ShObjIdl.TBPFLAG progressState)
- {
- return progressState switch
- {
- ShObjIdl.TBPFLAG.TBPF_INDETERMINATE => TaskBarProgressState.Indeterminate,
- ShObjIdl.TBPFLAG.TBPF_ERROR => TaskBarProgressState.Error,
- ShObjIdl.TBPFLAG.TBPF_PAUSED => TaskBarProgressState.Paused,
- ShObjIdl.TBPFLAG.TBPF_NORMAL => TaskBarProgressState.Normal,
- _ => TaskBarProgressState.None
+ TaskBarProgressState.Indeterminate => TBPFLAG.TBPF_INDETERMINATE,
+ TaskBarProgressState.Error => TBPFLAG.TBPF_ERROR,
+ TaskBarProgressState.Paused => TBPFLAG.TBPF_PAUSED,
+ TaskBarProgressState.Normal => TBPFLAG.TBPF_NORMAL,
+ _ => TBPFLAG.TBPF_NOPROGRESS,
};
}
}
diff --git a/src/Wpf.Ui/Interop/User32.cs b/src/Wpf.Ui/Interop/User32.cs
deleted file mode 100644
index d2d7e10cc..000000000
--- a/src/Wpf.Ui/Interop/User32.cs
+++ /dev/null
@@ -1,1600 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-/* This Source Code is partially based on reverse engineering of the Windows Operating System,
- and is intended for use on Windows systems only.
- This Source Code is partially based on the source code provided by the .NET Foundation.
-
- NOTE:
- I split unmanaged code stuff into the NativeMethods library.
- If you have suggestions for the code below, please submit your changes there.
- https://github.com/lepoco/nativemethods */
-
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop;
-
-// ReSharper disable IdentifierTypo
-// ReSharper disable InconsistentNaming
-#pragma warning disable SA1300 // Element should begin with upper-case letter
-#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
-#pragma warning disable SA1401 // Fields should be private
-
-///
-/// USER procedure declarations, constant definitions and macros.
-///
-internal static class User32
-{
- ///
- /// SetWindowPos options
- ///
- [Flags]
- public enum SWP
- {
- ASYNCWINDOWPOS = 0x4000,
- DEFERERASE = 0x2000,
- DRAWFRAME = 0x0020,
- FRAMECHANGED = DRAWFRAME,
- HIDEWINDOW = 0x0080,
- NOACTIVATE = 0x0010,
- NOCOPYBITS = 0x0100,
- NOMOVE = 0x0002,
- NOOWNERZORDER = 0x0200,
- NOREDRAW = 0x0008,
- NOREPOSITION = NOOWNERZORDER,
- NOSENDCHANGING = 0x0400,
- NOSIZE = 0x0001,
- NOZORDER = 0x0004,
- SHOWWINDOW = 0x0040,
- }
-
- ///
- /// EnableMenuItem uEnable values, MF_*
- ///
- [Flags]
- public enum MF : uint
- {
- ///
- /// Possible return value for EnableMenuItem
- ///
- DOES_NOT_EXIST = unchecked((uint)-1),
- ENABLED = 0,
- BYCOMMAND = ENABLED,
- GRAYED = 1,
- DISABLED = 2,
- }
-
- ///
- /// Menu item element.
- ///
- public enum SC
- {
- SIZE = 0xF000,
- MOVE = 0xF010,
- MINIMIZE = 0xF020,
- MAXIMIZE = 0xF030,
- NEXTWINDOW = 0xF040,
- PREVWINDOW = 0xF050,
- CLOSE = 0xF060,
- VSCROLL = 0xF070,
- HSCROLL = 0xF080,
- MOUSEMENU = 0xF090,
- KEYMENU = 0xF100,
- ARRANGE = 0xF110,
- RESTORE = 0xF120,
- TASKLIST = 0xF130,
- SCREENSAVE = 0xF140,
- HOTKEY = 0xF150,
- DEFAULT = 0xF160,
- MONITORPOWER = 0xF170,
- CONTEXTHELP = 0xF180,
- SEPARATOR = 0xF00F,
-
- ///
- /// SCF_ISSECURE
- ///
- F_ISSECURE = 0x00000001,
- ICON = MINIMIZE,
- ZOOM = MAXIMIZE,
- }
-
- ///
- /// WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes
- ///
- public enum WM_NCHITTEST
- {
- ///
- /// Hit test returned error.
- ///
- HTERROR = unchecked(-2),
-
- ///
- /// Hit test returned transparent.
- ///
- HTTRANSPARENT = unchecked(-1),
-
- ///
- /// On the screen background or on a dividing line between windows.
- ///
- HTNOWHERE = 0,
-
- ///
- /// In a client area.
- ///
- HTCLIENT = 1,
-
- ///
- /// In a title bar.
- ///
- HTCAPTION = 2,
-
- ///
- /// In a window menu or in a Close button in a child window.
- ///
- HTSYSMENU = 3,
-
- ///
- /// In a size box (same as HTSIZE).
- ///
- HTGROWBOX = 4,
- HTSIZE = HTGROWBOX,
-
- ///
- /// In a menu.
- ///
- HTMENU = 5,
-
- ///
- /// In a horizontal scroll bar.
- ///
- HTHSCROLL = 6,
-
- ///
- /// In the vertical scroll bar.
- ///
- HTVSCROLL = 7,
-
- ///
- /// In a Minimize button.
- ///
- HTMINBUTTON = 8,
-
- ///
- /// In a Maximize button.
- ///
- HTMAXBUTTON = 9,
-
- // ZOOM = 9,
-
- ///
- /// In the left border of a resizable window (the user can click the mouse to resize the window horizontally).
- ///
- HTLEFT = 10,
-
- ///
- /// In the right border of a resizable window (the user can click the mouse to resize the window horizontally).
- ///
- HTRIGHT = 11,
-
- ///
- /// In the upper-horizontal border of a window.
- ///
- HTTOP = 12,
-
- // From 10.0.22000.0\um\WinUser.h
- HTTOPLEFT = 13,
- HTTOPRIGHT = 14,
- HTBOTTOM = 15,
- HTBOTTOMLEFT = 16,
- HTBOTTOMRIGHT = 17,
- HTBORDER = 18,
- HTREDUCE = HTMINBUTTON,
- HTZOOM = HTMAXBUTTON,
- HTSIZEFIRST = HTLEFT,
- HTSIZELAST = HTBOTTOMRIGHT,
- HTOBJECT = 19,
- HTCLOSE = 20,
- HTHELP = 21
- }
-
- ///
- /// Window long flags.
- ///
- ///
- [Flags]
- public enum GWL
- {
- ///
- /// Sets a new extended window style.
- ///
- GWL_EXSTYLE = -20,
-
- ///
- /// Sets a new application instance handle.
- ///
- GWLP_HINSTANCE = -6,
-
- ///
- /// Sets a new hWnd parent.
- ///
- GWLP_HWNDPARENT = -8,
-
- ///
- /// Sets a new identifier of the child window. The window cannot be a top-level window.
- ///
- GWL_ID = -12,
-
- ///
- /// Sets a new window style.
- ///
- GWL_STYLE = -16,
-
- ///
- /// Sets the user data associated with the window.
- /// This data is intended for use by the application that created the window. Its value is initially zero.
- ///
- GWL_USERDATA = -21,
-
- ///
- /// Sets a new address for the window procedure.
- /// You cannot change this attribute if the window does not belong to the same process as the calling thread.
- ///
- GWL_WNDPROC = -4,
-
- ///
- /// Sets new extra information that is private to the application, such as handles or pointers.
- ///
- DWLP_USER = 0x8,
-
- ///
- /// Sets the return value of a message processed in the dialog box procedure.
- ///
- DWLP_MSGRESULT = 0x0,
-
- ///
- /// Sets the new address of the dialog box procedure.
- ///
- DWLP_DLGPROC = 0x4
- }
-
- ///
- /// Window composition attributes.
- ///
- public enum WCA
- {
- WCA_UNDEFINED = 0,
- WCA_NCRENDERING_ENABLED = 1,
- WCA_NCRENDERING_POLICY = 2,
- WCA_TRANSITIONS_FORCEDISABLED = 3,
- WCA_ALLOW_NCPAINT = 4,
- WCA_CAPTION_BUTTON_BOUNDS = 5,
- WCA_NONCLIENT_RTL_LAYOUT = 6,
- WCA_FORCE_ICONIC_REPRESENTATION = 7,
- WCA_EXTENDED_FRAME_BOUNDS = 8,
- WCA_HAS_ICONIC_BITMAP = 9,
- WCA_THEME_ATTRIBUTES = 10,
- WCA_NCRENDERING_EXILED = 11,
- WCA_NCADORNMENTINFO = 12,
- WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
- WCA_VIDEO_OVERLAY_ACTIVE = 14,
- WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
- WCA_DISALLOW_PEEK = 16,
- WCA_CLOAK = 17,
- WCA_CLOAKED = 18,
- WCA_ACCENT_POLICY = 19,
- WCA_FREEZE_REPRESENTATION = 20,
- WCA_EVER_UNCLOAKED = 21,
- WCA_VISUAL_OWNER = 22,
- WCA_HOLOGRAPHIC = 23,
- WCA_EXCLUDED_FROM_DDA = 24,
- WCA_PASSIVEUPDATEMODE = 25,
- WCA_USEDARKMODECOLORS = 26,
- WCA_CORNER_STYLE = 27,
- WCA_PART_COLOR = 28,
- WCA_DISABLE_MOVESIZE_FEEDBACK = 29,
- WCA_LAST = 30
- }
-
- [Flags]
- public enum ACCENT_FLAGS
- {
- DrawLeftBorder = 0x20,
- DrawTopBorder = 0x40,
- DrawRightBorder = 0x80,
- DrawBottomBorder = 0x100,
- DrawAllBorders = DrawLeftBorder | DrawTopBorder | DrawRightBorder | DrawBottomBorder
- }
-
- ///
- /// DWM window accent state.
- ///
- public enum ACCENT_STATE
- {
- ACCENT_DISABLED = 0,
- ACCENT_ENABLE_GRADIENT = 1,
- ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
- ACCENT_ENABLE_BLURBEHIND = 3,
- ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
- ACCENT_INVALID_STATE = 5
- }
-
- ///
- /// WCA window accent policy.
- ///
- [StructLayout(LayoutKind.Sequential)]
- public struct ACCENT_POLICY
- {
- public ACCENT_STATE nAccentState;
- public uint nFlags;
- public uint nColor;
- public uint nAnimationId;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct WINCOMPATTRDATA
- {
- public WCA Attribute;
- public IntPtr Data;
- public int SizeOfData;
- }
-
- ///
- /// CS_*
- ///
- [Flags]
- public enum CS : uint
- {
- VREDRAW = 0x0001,
- HREDRAW = 0x0002,
- DBLCLKS = 0x0008,
- OWNDC = 0x0020,
- CLASSDC = 0x0040,
- PARENTDC = 0x0080,
- NOCLOSE = 0x0200,
- SAVEBITS = 0x0800,
- BYTEALIGNCLIENT = 0x1000,
- BYTEALIGNWINDOW = 0x2000,
- GLOBALCLASS = 0x4000,
- IME = 0x00010000,
- DROPSHADOW = 0x00020000
- }
-
- ///
- /// MSGFLT_*. New in Vista. Realiased in Windows 7.
- ///
- public enum MSGFLT
- {
- // Win7 versions of this enum:
-
- ///
- /// Resets the window message filter for hWnd to the default. Any message allowed globally or process-wide will get through, but any message not included in those two categories, and which comes from a lower privileged process, will be blocked.
- ///
- RESET = 0,
-
- ///
- /// Allows the message through the filter. This enables the message to be received by hWnd, regardless of the source of the message, even it comes from a lower privileged process.
- ///
- ALLOW = 1,
-
- ///
- /// Blocks the message to be delivered to hWnd if it comes from a lower privileged process, unless the message is allowed process-wide by using the ChangeWindowMessageFilter function or globally.
- ///
- DISALLOW = 2,
-
- // Vista versions of this enum:
- // ADD = 1,
- // REMOVE = 2,
- }
-
- ///
- /// MSGFLTINFO.
- ///
- public enum MSGFLTINFO
- {
- NONE = 0,
- ALREADYALLOWED_FORWND = 1,
- ALREADYDISALLOWED_FORWND = 2,
- ALLOWED_HIGHER = 3,
- }
-
- ///
- /// Win7 only.
- ///
- [StructLayout(LayoutKind.Sequential)]
- public struct CHANGEFILTERSTRUCT
- {
- public uint cbSize;
- public MSGFLTINFO ExtStatus;
- }
-
- ///
- /// Window message values, WM_*
- ///
- public enum WM
- {
- NULL = 0x0000,
- CREATE = 0x0001,
- DESTROY = 0x0002,
- MOVE = 0x0003,
- SIZE = 0x0005,
- ACTIVATE = 0x0006,
- SETFOCUS = 0x0007,
- KILLFOCUS = 0x0008,
- ENABLE = 0x000A,
- SETREDRAW = 0x000B,
- SETTEXT = 0x000C,
- GETTEXT = 0x000D,
- GETTEXTLENGTH = 0x000E,
- PAINT = 0x000F,
- CLOSE = 0x0010,
- QUERYENDSESSION = 0x0011,
- QUIT = 0x0012,
- QUERYOPEN = 0x0013,
- ERASEBKGND = 0x0014,
- SYSCOLORCHANGE = 0x0015,
- SHOWWINDOW = 0x0018,
- CTLCOLOR = 0x0019,
- WININICHANGE = 0x001A,
- SETTINGCHANGE = WININICHANGE,
- ACTIVATEAPP = 0x001C,
- SETCURSOR = 0x0020,
- MOUSEACTIVATE = 0x0021,
- CHILDACTIVATE = 0x0022,
- QUEUESYNC = 0x0023,
- GETMINMAXINFO = 0x0024,
-
- WINDOWPOSCHANGING = 0x0046,
- WINDOWPOSCHANGED = 0x0047,
-
- CONTEXTMENU = 0x007B,
- STYLECHANGING = 0x007C,
- STYLECHANGED = 0x007D,
- DISPLAYCHANGE = 0x007E,
- GETICON = 0x007F,
- SETICON = 0x0080,
- NCCREATE = 0x0081,
- NCDESTROY = 0x0082,
- NCCALCSIZE = 0x0083,
- NCHITTEST = 0x0084,
- NCPAINT = 0x0085,
- NCACTIVATE = 0x0086,
- GETDLGCODE = 0x0087,
- SYNCPAINT = 0x0088,
- NCMOUSEMOVE = 0x00A0,
- NCLBUTTONDOWN = 0x00A1,
- NCLBUTTONUP = 0x00A2,
- NCLBUTTONDBLCLK = 0x00A3,
- NCRBUTTONDOWN = 0x00A4,
- NCRBUTTONUP = 0x00A5,
- NCRBUTTONDBLCLK = 0x00A6,
- NCMBUTTONDOWN = 0x00A7,
- NCMBUTTONUP = 0x00A8,
- NCMBUTTONDBLCLK = 0x00A9,
-
- SYSKEYDOWN = 0x0104,
- SYSKEYUP = 0x0105,
- SYSCHAR = 0x0106,
- SYSDEADCHAR = 0x0107,
- COMMAND = 0x0111,
- SYSCOMMAND = 0x0112,
-
- MOUSEMOVE = 0x0200,
- LBUTTONDOWN = 0x0201,
- LBUTTONUP = 0x0202,
- LBUTTONDBLCLK = 0x0203,
- RBUTTONDOWN = 0x0204,
- RBUTTONUP = 0x0205,
- RBUTTONDBLCLK = 0x0206,
- MBUTTONDOWN = 0x0207,
- MBUTTONUP = 0x0208,
- MBUTTONDBLCLK = 0x0209,
- MOUSEWHEEL = 0x020A,
- XBUTTONDOWN = 0x020B,
- XBUTTONUP = 0x020C,
- XBUTTONDBLCLK = 0x020D,
- MOUSEHWHEEL = 0x020E,
- PARENTNOTIFY = 0x0210,
-
- CAPTURECHANGED = 0x0215,
- POWERBROADCAST = 0x0218,
- DEVICECHANGE = 0x0219,
-
- ENTERSIZEMOVE = 0x0231,
- EXITSIZEMOVE = 0x0232,
-
- IME_SETCONTEXT = 0x0281,
- IME_NOTIFY = 0x0282,
- IME_CONTROL = 0x0283,
- IME_COMPOSITIONFULL = 0x0284,
- IME_SELECT = 0x0285,
- IME_CHAR = 0x0286,
- IME_REQUEST = 0x0288,
- IME_KEYDOWN = 0x0290,
- IME_KEYUP = 0x0291,
-
- NCMOUSELEAVE = 0x02A2,
-
- TABLET_DEFBASE = 0x02C0,
-
- // WM_TABLET_MAXOFFSET = 0x20,
- TABLET_ADDED = TABLET_DEFBASE + 8,
- TABLET_DELETED = TABLET_DEFBASE + 9,
- TABLET_FLICK = TABLET_DEFBASE + 11,
- TABLET_QUERYSYSTEMGESTURESTATUS = TABLET_DEFBASE + 12,
-
- CUT = 0x0300,
- COPY = 0x0301,
- PASTE = 0x0302,
- CLEAR = 0x0303,
- UNDO = 0x0304,
- RENDERFORMAT = 0x0305,
- RENDERALLFORMATS = 0x0306,
- DESTROYCLIPBOARD = 0x0307,
- DRAWCLIPBOARD = 0x0308,
- PAINTCLIPBOARD = 0x0309,
- VSCROLLCLIPBOARD = 0x030A,
- SIZECLIPBOARD = 0x030B,
- ASKCBFORMATNAME = 0x030C,
- CHANGECBCHAIN = 0x030D,
- HSCROLLCLIPBOARD = 0x030E,
- QUERYNEWPALETTE = 0x030F,
- PALETTEISCHANGING = 0x0310,
- PALETTECHANGED = 0x0311,
- HOTKEY = 0x0312,
- PRINT = 0x0317,
- PRINTCLIENT = 0x0318,
- APPCOMMAND = 0x0319,
- THEMECHANGED = 0x031A,
-
- DWMCOMPOSITIONCHANGED = 0x031E,
- DWMNCRENDERINGCHANGED = 0x031F,
- DWMCOLORIZATIONCOLORCHANGED = 0x0320,
- DWMWINDOWMAXIMIZEDCHANGE = 0x0321,
-
- GETTITLEBARINFOEX = 0x033F,
-
- DWMSENDICONICTHUMBNAIL = 0x0323,
- DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326,
-
- USER = 0x0400,
-
- ///
- /// This is the hard-coded message value used by WinForms for Shell_NotifyIcon.
- /// It's relatively safe to reuse.
- ///
- TRAYMOUSEMESSAGE = 0x800, // WM_USER + 1024
- APP = 0x8000,
- }
-
- ///
- /// WindowStyle values, WS_*
- ///
- [Flags]
- public enum WS : long
- {
- OVERLAPPED = 0x00000000,
- POPUP = 0x80000000,
- CHILD = 0x40000000,
- MINIMIZE = 0x20000000,
- VISIBLE = 0x10000000,
- DISABLED = 0x08000000,
- CLIPSIBLINGS = 0x04000000,
- CLIPCHILDREN = 0x02000000,
- MAXIMIZE = 0x01000000,
- BORDER = 0x00800000,
- DLGFRAME = 0x00400000,
- VSCROLL = 0x00200000,
- HSCROLL = 0x00100000,
- SYSMENU = 0x00080000,
- THICKFRAME = 0x00040000,
- GROUP = 0x00020000,
- TABSTOP = 0x00010000,
-
- MINIMIZEBOX = GROUP,
- MAXIMIZEBOX = TABSTOP,
-
- CAPTION = BORDER | DLGFRAME,
- TILED = OVERLAPPED,
- ICONIC = MINIMIZE,
- SIZEBOX = THICKFRAME,
-
- OVERLAPPEDWINDOW = OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX,
- TILEDWINDOW = OVERLAPPEDWINDOW,
-
- POPUPWINDOW = POPUP | BORDER | SYSMENU,
- CHILDWINDOW = CHILD,
- }
-
- ///
- /// Window style extended values, WS_EX_*
- ///
- [Flags]
- public enum WS_EX : long
- {
- NONE = 0x00000000,
- DLGMODALFRAME = 0x00000001,
- NOPARENTNOTIFY = 0x00000004,
- TOPMOST = 0x00000008,
- ACCEPTFILES = 0x00000010,
- TRANSPARENT = 0x00000020,
- MDICHILD = 0x00000040,
- TOOLWINDOW = 0x00000080,
- WINDOWEDGE = 0x00000100,
- CLIENTEDGE = 0x00000200,
- CONTEXTHELP = 0x00000400,
- RIGHT = 0x00001000,
- LEFT = NONE,
- RTLREADING = 0x00002000,
- LTRREADING = NONE,
- LEFTSCROLLBAR = 0x00004000,
- RIGHTSCROLLBAR = NONE,
- CONTROLPARENT = 0x00010000,
- STATICEDGE = 0x00020000,
- APPWINDOW = 0x00040000,
- LAYERED = 0x00080000,
- NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children
- LAYOUTRTL = 0x00400000, // Right to left mirroring
- COMPOSITED = 0x02000000,
- NOACTIVATE = 0x08000000,
- OVERLAPPEDWINDOW = WINDOWEDGE | CLIENTEDGE,
- PALETTEWINDOW = WINDOWEDGE | TOOLWINDOW | TOPMOST,
- }
-
- ///
- /// SystemMetrics. SM_*
- ///
- public enum SM
- {
- CXSCREEN = 0,
- CYSCREEN = 1,
- CXVSCROLL = 2,
- CYHSCROLL = 3,
- CYCAPTION = 4,
- CXBORDER = 5,
- CYBORDER = 6,
- CXFIXEDFRAME = 7,
- CYFIXEDFRAME = 8,
- CYVTHUMB = 9,
- CXHTHUMB = 10,
- CXICON = 11,
- CYICON = 12,
- CXCURSOR = 13,
- CYCURSOR = 14,
- CYMENU = 15,
- CXFULLSCREEN = 16,
- CYFULLSCREEN = 17,
- CYKANJIWINDOW = 18,
- MOUSEPRESENT = 19,
- CYVSCROLL = 20,
- CXHSCROLL = 21,
- DEBUG = 22,
- SWAPBUTTON = 23,
- CXMIN = 28,
- CYMIN = 29,
- CXSIZE = 30,
- CYSIZE = 31,
- CXFRAME = 32,
- CXSIZEFRAME = CXFRAME,
- CYFRAME = 33,
- CYSIZEFRAME = CYFRAME,
- CXMINTRACK = 34,
- CYMINTRACK = 35,
- CXDOUBLECLK = 36,
- CYDOUBLECLK = 37,
- CXICONSPACING = 38,
- CYICONSPACING = 39,
- MENUDROPALIGNMENT = 40,
- PENWINDOWS = 41,
- DBCSENABLED = 42,
- CMOUSEBUTTONS = 43,
- SECURE = 44,
- CXEDGE = 45,
- CYEDGE = 46,
- CXMINSPACING = 47,
- CYMINSPACING = 48,
- CXSMICON = 49,
- CYSMICON = 50,
- CYSMCAPTION = 51,
- CXSMSIZE = 52,
- CYSMSIZE = 53,
- CXMENUSIZE = 54,
- CYMENUSIZE = 55,
- ARRANGE = 56,
- CXMINIMIZED = 57,
- CYMINIMIZED = 58,
- CXMAXTRACK = 59,
- CYMAXTRACK = 60,
- CXMAXIMIZED = 61,
- CYMAXIMIZED = 62,
- NETWORK = 63,
- CLEANBOOT = 67,
- CXDRAG = 68,
- CYDRAG = 69,
- SHOWSOUNDS = 70,
- CXMENUCHECK = 71,
- CYMENUCHECK = 72,
- SLOWMACHINE = 73,
- MIDEASTENABLED = 74,
- MOUSEWHEELPRESENT = 75,
- XVIRTUALSCREEN = 76,
- YVIRTUALSCREEN = 77,
- CXVIRTUALSCREEN = 78,
- CYVIRTUALSCREEN = 79,
- CMONITORS = 80,
- SAMEDISPLAYFORMAT = 81,
- IMMENABLED = 82,
- CXFOCUSBORDER = 83,
- CYFOCUSBORDER = 84,
- TABLETPC = 86,
- MEDIACENTER = 87,
- CXPADDEDBORDER = 92,
- REMOTESESSION = 0x1000,
- REMOTECONTROL = 0x2001,
- }
-
- ///
- /// ShowWindow options
- ///
- public enum SW
- {
- HIDE = 0,
- SHOWNORMAL = 1,
- NORMAL = SHOWNORMAL,
- SHOWMINIMIZED = 2,
- SHOWMAXIMIZED = 3,
- MAXIMIZE = SHOWMAXIMIZED,
- SHOWNOACTIVATE = 4,
- SHOW = 5,
- MINIMIZE = 6,
- SHOWMINNOACTIVE = 7,
- SHOWNA = 8,
- RESTORE = 9,
- SHOWDEFAULT = 10,
- FORCEMINIMIZE = 11,
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public class WINDOWPLACEMENT
- {
- public int length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
- public int flags;
- public SW showCmd;
- public WinDef.POINT ptMinPosition;
- public WinDef.POINT ptMaxPosition;
- public WinDef.RECT rcNormalPosition;
- }
-
- ///
- /// Contains window class information. It is used with the and GetClassInfoEx functions.
- ///
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- public struct WNDCLASSEX
- {
- ///
- /// The size, in bytes, of this structure. Set this member to sizeof(WNDCLASSEX). Be sure to set this member before calling the GetClassInfoEx function.
- ///
- public int cbSize;
-
- ///
- /// The class style(s). This member can be any combination of the Class Styles.
- ///
- public CS style;
-
- ///
- /// A pointer to the window procedure. You must use the CallWindowProc function to call the window procedure. For more information, see WindowProc.
- ///
- public WndProc lpfnWndProc;
-
- ///
- /// The number of extra bytes to allocate following the window-class structure. The system initializes the bytes to zero.
- ///
- public int cbClsExtra;
-
- ///
- /// The number of extra bytes to allocate following the window instance. The system initializes the bytes to zero. If an application uses WNDCLASSEX to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA.
- ///
- public int cbWndExtra;
-
- ///
- /// A handle to the instance that contains the window procedure for the class.
- ///
- public IntPtr hInstance;
-
- ///
- /// A handle to the class icon. This member must be a handle to an icon resource. If this member is NULL, the system provides a default icon.
- ///
- public IntPtr hIcon;
-
- ///
- /// A handle to the class cursor. This member must be a handle to a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window.
- ///
- public IntPtr hCursor;
-
- ///
- /// A handle to the class background brush. This member can be a handle to the brush to be used for painting the background, or it can be a color value.
- ///
- public IntPtr hbrBackground;
-
- ///
- /// Pointer to a null-terminated character string that specifies the resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu.
- ///
- [MarshalAs(UnmanagedType.LPWStr)]
- public string lpszMenuName;
-
- ///
- /// A pointer to a null-terminated string or is an atom. If this parameter is an atom, it must be a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpszClassName; the high-order word must be zero.
- ///
- [MarshalAs(UnmanagedType.LPWStr)]
- public string lpszClassName;
-
- ///
- /// A handle to a small icon that is associated with the window class. If this member is NULL, the system searches the icon resource specified by the hIcon member for an icon of the appropriate size to use as the small icon.
- ///
- public IntPtr hIconSm;
- }
-
- ///
- /// Delegate declaration that matches native WndProc signatures.
- ///
- public delegate IntPtr WndProc(IntPtr hWnd, WM uMsg, IntPtr wParam, IntPtr lParam);
-
- ///
- /// Delegate declaration that matches native WndProc signatures.
- ///
- public delegate IntPtr WndProcHook(IntPtr hWnd, WM uMsg, IntPtr wParam, IntPtr lParam, ref bool handled);
-
- ///
- /// Delegate declaration that matches managed WndProc signatures.
- ///
- public delegate IntPtr MessageHandler(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled);
-
- ///
- /// The ReleaseDC function releases a device context (DC), freeing it for use by other applications.
- /// The effect of the ReleaseDC function depends on the type of DC. It frees only common and window DCs. It has no effect on class or private DCs.
- ///
- /// A handle to the window whose DC is to be released.
- /// A handle to the DC to be released.
- /// The return value indicates whether the DC was released. If the DC was released, the return value is 1. If the DC was not released, the return value is zero.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern int ReleaseDC([In] IntPtr hWnd, [In] IntPtr hDC);
-
- ///
- /// Calculates the required size of the window rectangle, based on the desired size of the client rectangle.
- /// The window rectangle can then be passed to the CreateWindowEx function to create a window whose client area is the desired size.
- ///
- /// A pointer to a RECT structure that contains the coordinates of the top-left and bottom-right corners of the desired client area.
- /// The window style of the window whose required size is to be calculated. Note that you cannot specify the WS_OVERLAPPED style.
- /// Indicates whether the window has a menu.
- /// The extended window style of the window whose required size is to be calculated.
- /// If the function succeeds, the return value is nonzero.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool AdjustWindowRectEx(
- [In] ref Rect lpRect,
- [In] WS dwStyle,
- [In] [MarshalAs(UnmanagedType.Bool)] bool bMenu,
- [In] WS_EX dwExStyle
- );
-
- ///
- /// [Using the ChangeWindowMessageFilter function is not recommended, as it has process-wide scope. Instead, use the ChangeWindowMessageFilterEx function to control access to specific windows as needed. ChangeWindowMessageFilter may not be supported in future versions of Windows.
- /// Adds or removes a message from the User Interface Privilege Isolation(UIPI) message filter.
- ///
- /// The message to add to or remove from the filter.
- /// The action to be performed. One of the following values.
- /// if successful; otherwise, . To get extended error information, call .
- [DllImport(Libraries.User32, CharSet = CharSet.Auto, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool ChangeWindowMessageFilter([In] WM message, [In] MSGFLT dwFlag);
-
- ///
- /// Modifies the User Interface Privilege Isolation (UIPI) message filter for a specified window.
- ///
- /// A handle to the window whose UIPI message filter is to be modified.
- /// The message that the message filter allows through or blocks.
- /// The action to be performed.
- /// Optional pointer to a structure.
- /// If the function succeeds, it returns ; otherwise, it returns . To get extended error information, call .
- [DllImport(Libraries.User32, CharSet = CharSet.Auto, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool ChangeWindowMessageFilterEx(
- [In] IntPtr hWnd,
- [In] WM message,
- [In] MSGFLT action,
- [In, Out, Optional] ref CHANGEFILTERSTRUCT pChangeFilterStruct
- );
-
- ///
- /// Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.
- /// Unicode declaration for
- ///
- /// A handle to the window whose window procedure is to receive the message.
- /// The message to be posted.
- /// Additional message-specific information.
- /// Additional message-specific information.~
- /// If the function succeeds, the return value is nonzero.
- [DllImport(Libraries.User32, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool PostMessageW(
- [In, Optional] IntPtr hWnd,
- [In] WM Msg,
- [In] IntPtr wParam,
- [In] IntPtr lParam
- );
-
- ///
- /// Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.
- /// ANSI declaration for
- ///
- /// A handle to the window whose window procedure is to receive the message.
- /// The message to be posted.
- /// Additional message-specific information.
- /// Additional message-specific information.~
- /// If the function succeeds, the return value is nonzero.
- [DllImport(Libraries.User32, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool PostMessageA(
- [In, Optional] IntPtr hWnd,
- [In] WM Msg,
- [In] IntPtr wParam,
- [In] IntPtr lParam
- );
-
- ///
- /// Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.
- ///
- /// A handle to the window whose window procedure is to receive the message.
- /// The message to be posted.
- /// Additional message-specific information.
- /// Additional message-specific information.~
- /// If the function succeeds, the return value is nonzero.
- [DllImport(Libraries.User32, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool PostMessage(
- [In, Optional] IntPtr hWnd,
- [In] WM Msg,
- [In] IntPtr wParam,
- [In] IntPtr lParam
- );
-
- ///
- /// Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
- ///
- /// A handle to the window whose window procedure will receive the message.
- /// The message to be sent.
- /// Additional message-specific information.
- /// Additional message-specific information.~
- /// The return value specifies the result of the message processing; it depends on the message sent.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern int SendMessage(
- [In] IntPtr hWnd,
- [In] WM wMsg,
- [In] IntPtr wParam,
- [In] IntPtr lParam
- );
-
- ///
- /// Creates an overlapped, pop-up, or child window with an extended window style; otherwise,
- /// this function is identical to the CreateWindow function. For more information about
- /// creating a window and for full descriptions of the other parameters of CreateWindowEx, see CreateWindow.
- ///
- /// The extended window style of the window being created.
- /// A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function.
- /// The window name. If the window style specifies a title bar, the window title pointed to by lpWindowName is displayed in the title bar.
- /// The style of the window being created. This parameter can be a combination of the window style values, plus the control styles indicated in the Remarks section.
- /// The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates.
- /// The initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates.
- /// The width, in device units, of the window. For overlapped windows, nWidth is the window's width, in screen coordinates, or CW_USEDEFAULT.
- /// The height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If the nWidth parameter is set to CW_USEDEFAULT, the system ignores nHeight.
- /// A handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows.
- /// A handle to a menu, or specifies a child-window identifier, depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used.
- /// A handle to the instance of the module to be associated with the window.
- /// Pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns.
- /// If the function succeeds, the return value is a handle to the new window.
- [DllImport(Libraries.User32, SetLastError = true, CharSet = CharSet.Unicode)]
- public static extern IntPtr CreateWindowExW(
- [In] WS_EX dwExStyle,
- [In, Optional] [MarshalAs(UnmanagedType.LPWStr)] string lpClassName,
- [In, Optional] [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName,
- [In] WS dwStyle,
- [In] int x,
- [In] int y,
- [In] int nWidth,
- [In] int nHeight,
- [In, Optional] IntPtr hWndParent,
- [In, Optional] IntPtr hMenu,
- [In, Optional] IntPtr hInstance,
- [In, Optional] IntPtr lpParam
- );
-
- ///
- /// Creates an overlapped, pop-up, or child window with an extended window style; otherwise,
- /// this function is identical to the CreateWindow function. For more information about
- /// creating a window and for full descriptions of the other parameters of CreateWindowEx, see CreateWindow.
- ///
- /// The extended window style of the window being created.
- /// A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function.
- /// The window name. If the window style specifies a title bar, the window title pointed to by lpWindowName is displayed in the title bar.
- /// The style of the window being created. This parameter can be a combination of the window style values, plus the control styles indicated in the Remarks section.
- /// The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates.
- /// The initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates.
- /// The width, in device units, of the window. For overlapped windows, nWidth is the window's width, in screen coordinates, or CW_USEDEFAULT.
- /// The height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If the nWidth parameter is set to CW_USEDEFAULT, the system ignores nHeight.
- /// A handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows.
- /// A handle to a menu, or specifies a child-window identifier, depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used.
- /// A handle to the instance of the module to be associated with the window.
- /// Pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns.
- /// If the function succeeds, the return value is a handle to the new window.
- public static IntPtr CreateWindowEx(
- [In] WS_EX dwExStyle,
- [In] string lpClassName,
- [In] string lpWindowName,
- [In] WS dwStyle,
- [In] int x,
- [In] int y,
- [In] int nWidth,
- [In] int nHeight,
- [In, Optional] IntPtr hWndParent,
- [In, Optional] IntPtr hMenu,
- [In, Optional] IntPtr hInstance,
- [In, Optional] IntPtr lpParam
- )
- {
- IntPtr ret = CreateWindowExW(
- dwExStyle,
- lpClassName,
- lpWindowName,
- dwStyle,
- x,
- y,
- nWidth,
- nHeight,
- hWndParent,
- hMenu,
- hInstance,
- lpParam
- );
-
- if (ret == IntPtr.Zero)
- {
- // HRESULT.ThrowLastError();
- throw new Exception("Unable to create a window");
- }
-
- return ret;
- }
-
- ///
- /// Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function.
- /// Unicode declaration for
- ///
- /// A pointer to a structure. You must fill the structure with the appropriate class attributes before passing it to the function.
- /// If the function succeeds, the return value is a class atom that uniquely identifies the class being registered.
- [DllImport(Libraries.User32, SetLastError = true, CharSet = CharSet.Unicode)]
- public static extern short RegisterClassExW([In] ref WNDCLASSEX lpwcx);
-
- ///
- /// Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function.
- /// ANSI declaration for
- ///
- /// A pointer to a structure. You must fill the structure with the appropriate class attributes before passing it to the function.
- /// If the function succeeds, the return value is a class atom that uniquely identifies the class being registered.
- [DllImport(Libraries.User32, SetLastError = true)]
- public static extern short RegisterClassExA([In] ref WNDCLASSEX lpwcx);
-
- ///
- /// Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function.
- ///
- /// A pointer to a structure. You must fill the structure with the appropriate class attributes before passing it to the function.
- /// If the function succeeds, the return value is a class atom that uniquely identifies the class being registered.
- [DllImport(Libraries.User32, SetLastError = true)]
- public static extern short RegisterClassEx([In] ref WNDCLASSEX lpwcx);
-
- ///
- /// Calls the default window procedure to provide default processing for any window messages that an application does not process.
- /// This function ensures that every message is processed. DefWindowProc is called with the same parameters received by the window procedure.
- /// Unicode declaration for
- ///
- /// A handle to the window procedure that received the message.
- /// The message.
- /// Additional message information. The content of this parameter depends on the value of the Msg parameter.
- /// Additional message information. The content of this parameter depends on the value of the Msg parameter.~
- /// The return value is the result of the message processing and depends on the message.
- [DllImport(Libraries.User32, CharSet = CharSet.Unicode)]
- public static extern IntPtr DefWindowProcW(
- [In] IntPtr hWnd,
- [In] WM Msg,
- [In] IntPtr wParam,
- [In] IntPtr lParam
- );
-
- ///
- /// Calls the default window procedure to provide default processing for any window messages that an application does not process.
- /// This function ensures that every message is processed. DefWindowProc is called with the same parameters received by the window procedure.
- /// ANSI declaration for
- ///
- /// A handle to the window procedure that received the message.
- /// The message.
- /// Additional message information. The content of this parameter depends on the value of the Msg parameter.
- /// Additional message information. The content of this parameter depends on the value of the Msg parameter.~
- /// The return value is the result of the message processing and depends on the message.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr DefWindowProcA(
- [In] IntPtr hWnd,
- [In] WM Msg,
- [In] IntPtr wParam,
- [In] IntPtr lParam
- );
-
- ///
- /// Calls the default window procedure to provide default processing for any window messages that an application does not process.
- /// This function ensures that every message is processed. DefWindowProc is called with the same parameters received by the window procedure.
- ///
- /// A handle to the window procedure that received the message.
- /// The message.
- /// Additional message information. The content of this parameter depends on the value of the Msg parameter.
- /// Additional message information. The content of this parameter depends on the value of the Msg parameter.~
- /// The return value is the result of the message processing and depends on the message.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr DefWindowProc(
- [In] IntPtr hWnd,
- [In] WM Msg,
- [In] IntPtr wParam,
- [In] IntPtr lParam
- );
-
- ///
- /// Retrieves information about the specified window. The function also retrieves the 32-bit (DWORD) value at the specified offset into the extra window memory.
- /// If you are retrieving a pointer or a handle, this function has been superseded by the function.
- /// Unicode declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be retrieved.
- /// If the function succeeds, the return value is the requested value.
- [DllImport(Libraries.User32, CharSet = CharSet.Unicode)]
- public static extern long GetWindowLongW([In] IntPtr hWnd, [In] int nIndex);
-
- ///
- /// Retrieves information about the specified window. The function also retrieves the 32-bit (DWORD) value at the specified offset into the extra window memory.
- /// If you are retrieving a pointer or a handle, this function has been superseded by the function.
- /// ANSI declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be retrieved.
- /// If the function succeeds, the return value is the requested value.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern long GetWindowLongA([In] IntPtr hWnd, [In] int nIndex);
-
- ///
- /// Retrieves information about the specified window. The function also retrieves the 32-bit (DWORD) value at the specified offset into the extra window memory.
- /// If you are retrieving a pointer or a handle, this function has been superseded by the function.
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be retrieved.
- /// If the function succeeds, the return value is the requested value.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern long GetWindowLong([In] IntPtr hWnd, [In] int nIndex);
-
- ///
- /// Retrieves information about the specified window. The function also retrieves the 32-bit (DWORD) value at the specified offset into the extra window memory.
- /// If you are retrieving a pointer or a handle, this function has been superseded by the function.
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be retrieved.
- /// If the function succeeds, the return value is the requested value.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern long GetWindowLong([In] IntPtr hWnd, [In] GWL nIndex);
-
- ///
- /// Retrieves information about the specified window. The function also retrieves the value at a specified offset into the extra window memory.
- /// Unicode declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be retrieved.
- /// If the function succeeds, the return value is the requested value.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr GetWindowLongPtrW([In] IntPtr hWnd, [In] int nIndex);
-
- ///
- /// Retrieves information about the specified window. The function also retrieves the value at a specified offset into the extra window memory.
- /// ANSI declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be retrieved.
- /// If the function succeeds, the return value is the requested value.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr GetWindowLongPtrA([In] IntPtr hWnd, [In] int nIndex);
-
- ///
- /// Retrieves information about the specified window. The function also retrieves the value at a specified offset into the extra window memory.
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be retrieved.
- /// If the function succeeds, the return value is the requested value.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr GetWindowLongPtr([In] IntPtr hWnd, [In] int nIndex);
-
- ///
- /// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
- /// Note: This function has been superseded by the function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function.
- /// Unicode declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer.
- /// The replacement value.
- /// If the function succeeds, the return value is the previous value of the specified 32-bit integer.
- [DllImport(Libraries.User32, CharSet = CharSet.Unicode)]
- public static extern long SetWindowLongW([In] IntPtr hWnd, [In] int nIndex, [In] long dwNewLong);
-
- ///
- /// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
- /// Note: This function has been superseded by the function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function.
- /// ANSI declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer.
- /// The replacement value.
- /// If the function succeeds, the return value is the previous value of the specified 32-bit integer.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern long SetWindowLongA([In] IntPtr hWnd, [In] int nIndex, [In] long dwNewLong);
-
- ///
- /// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
- /// Note: This function has been superseded by the function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function.
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer.
- /// The replacement value.
- /// If the function succeeds, the return value is the previous value of the specified 32-bit integer.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern long SetWindowLong([In] IntPtr hWnd, [In] int nIndex, [In] long dwNewLong);
-
- ///
- /// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
- /// Note: This function has been superseded by the function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function.
- /// ANSI declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer.
- /// The replacement value.
- /// If the function succeeds, the return value is the previous value of the specified 32-bit integer.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern long SetWindowLong([In] IntPtr hWnd, [In] GWL nIndex, [In] long dwNewLong);
-
- ///
- /// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
- /// Note: This function has been superseded by the function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function.
- /// ANSI declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer.
- /// New window style.
- /// If the function succeeds, the return value is the previous value of the specified 32-bit integer.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern long SetWindowLong([In] IntPtr hWnd, [In] GWL nIndex, [In] WS dwNewLong);
-
- ///
- /// Changes an attribute of the specified window. The function also sets a value at the specified offset in the extra window memory.
- /// Unicode declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be set.
- /// The replacement value.
- /// If the function succeeds, the return value is the previous value of the specified offset.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr SetWindowLongPtrW([In] IntPtr hWnd, [In] int nIndex, [In] IntPtr dwNewLong);
-
- ///
- /// Changes an attribute of the specified window. The function also sets a value at the specified offset in the extra window memory.
- /// ANSI declaration for
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be set.
- /// The replacement value.
- /// If the function succeeds, the return value is the previous value of the specified offset.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr SetWindowLongPtrA([In] IntPtr hWnd, [In] int nIndex, [In] IntPtr dwNewLong);
-
- ///
- /// Changes an attribute of the specified window. The function also sets a value at the specified offset in the extra window memory.
- ///
- /// A handle to the window and, indirectly, the class to which the window belongs.
- /// The zero-based offset to the value to be set.
- /// The replacement value.
- /// If the function succeeds, the return value is the previous value of the specified offset.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern IntPtr SetWindowLongPtr([In] IntPtr hWnd, [In] int nIndex, [In] IntPtr dwNewLong);
-
- ///
- /// Changes an attribute of the specified window.
- ///
- [DllImport(Libraries.User32, CharSet = CharSet.Auto, SetLastError = true)]
- public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
-
- ///
- /// Destroys an icon and frees any memory the icon occupied.
- ///
- /// A handle to the icon to be destroyed. The icon must not be in use.
- /// If the function succeeds, the return value is nonzero.
- [DllImport(Libraries.User32)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool DestroyIcon([In] IntPtr handle);
-
- ///
- /// Determines whether the specified window handle identifies an existing window.
- ///
- /// A handle to the window to be tested.
- /// If the window handle identifies an existing window, the return value is nonzero.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool IsWindow([In] IntPtr hWnd);
-
- ///
- /// Destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it.
- ///
- /// A handle to the window to be destroyed.
- /// If the function succeeds, the return value is nonzero.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool DestroyWindow([In] IntPtr hWnd);
-
- ///
- /// Retrieves the show state and the restored, minimized, and maximized positions of the specified window.
- ///
- /// A handle to the window.
- /// A pointer to the structure that receives the show state and position information. Before calling GetWindowPlacement, set the length member to sizeof(WINDOWPLACEMENT). GetWindowPlacement fails if lpwndpl-> length is not set correctly.
- /// If the function succeeds, the return value is nonzero.
- [DllImport(Libraries.User32, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool GetWindowPlacement([In] IntPtr hWnd, [In] WINDOWPLACEMENT lpwndpl);
-
- ///
- /// Retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
- ///
- /// A handle to the window.
- /// A pointer to a RECT structure that receives the screen coordinates of the upper-left and lower-right corners of the window.
- /// If the function succeeds, the return value is nonzero.
- [DllImport(Libraries.User32, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool GetWindowRect([In] IntPtr hWnd, [Out] out Rect lpRect);
-
- ///
- /// Determines the visibility state of the specified window.
- ///
- /// A handle to the window to be tested.
- /// If the specified window, its parent window, its parent's parent window, and so forth, have the WS_VISIBLE style, the return value is nonzero. Otherwise, the return value is zero.
- [DllImport(Libraries.User32)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool IsWindowVisible([In] IntPtr hWnd);
-
- ///
- /// Determines whether the specified window is enabled for mouse and keyboard input.
- ///
- /// A handle to the window to be tested.
- /// If the window is enabled, the return value is nonzero.
- [DllImport(Libraries.User32, ExactSpelling = true)]
- internal static extern bool IsWindowEnabled(IntPtr hWnd);
-
- ///
- /// The MonitorFromWindow function retrieves a handle to the display monitor that has the largest area of intersection with the bounding rectangle of a specified window.
- ///
- /// A handle to the window of interest.
- /// Determines the function's return value if the window does not intersect any display monitor.
- /// If the window intersects one or more display monitor rectangles, the return value is an HMONITOR handle to the display monitor that has the largest area of intersection with the window.
- [DllImport(Libraries.User32)]
- public static extern IntPtr MonitorFromWindow(IntPtr hWnd, uint dwFlags);
-
- ///
- /// Retrieves the specified system metric or system configuration setting.
- /// Note that all dimensions retrieved by GetSystemMetrics are in pixels.
- ///
- /// The system metric or configuration setting to be retrieved. This parameter can be one of the values.
- /// Note that all SM_CX* values are widths and all SM_CY* values are heights. Also note that all settings designed to return Boolean data represent as any nonzero value, and as a zero value.
- /// If the function succeeds, the return value is the requested system metric or configuration setting.
- [DllImport(Libraries.User32)]
- public static extern int GetSystemMetrics([In] SM nIndex);
-
- ///
- /// Defines a new window message that is guaranteed to be unique throughout the system. The message value can be used when sending or posting messages.
- /// Unicode declaration for
- ///
- /// The message to be registered.
- /// If the message is successfully registered, the return value is a message identifier in the range 0xC000 through 0xFFFF.
- [DllImport(Libraries.User32, SetLastError = true, CharSet = CharSet.Unicode)]
- public static extern uint RegisterWindowMessageW([MarshalAs(UnmanagedType.LPWStr)] string lpString);
-
- ///
- /// Defines a new window message that is guaranteed to be unique throughout the system. The message value can be used when sending or posting messages.
- /// ANSI declaration for
- ///
- /// The message to be registered.
- /// If the message is successfully registered, the return value is a message identifier in the range 0xC000 through 0xFFFF.
- [DllImport(Libraries.User32, SetLastError = true, CharSet = CharSet.Auto)]
- public static extern uint RegisterWindowMessageA([MarshalAs(UnmanagedType.LPWStr)] string lpString);
-
- ///
- /// Defines a new window message that is guaranteed to be unique throughout the system. The message value can be used when sending or posting messages.
- ///
- /// The message to be registered.
- /// If the message is successfully registered, the return value is a message identifier in the range 0xC000 through 0xFFFF.
- [DllImport(Libraries.User32, SetLastError = true, CharSet = CharSet.Auto)]
- public static extern uint RegisterWindowMessage([MarshalAs(UnmanagedType.LPWStr)] string lpString);
-
- ///
- /// Activates a window. The window must be attached to the calling thread's message queue.
- ///
- /// A handle to the top-level window to be activated.
- /// If the function succeeds, the return value is the handle to the window that was previously active.
- [DllImport(Libraries.User32, SetLastError = true)]
- public static extern IntPtr SetActiveWindow(IntPtr hWnd);
-
- ///
- /// Brings the thread that created the specified window into the foreground and activates the window.
- /// Keyboard input is directed to the window, and various visual cues are changed for the user.
- /// The system assigns a slightly higher priority to the thread that created the foreground window than it does to other threads.
- ///
- /// A handle to the window that should be activated and brought to the foreground.
- /// If the window was brought to the foreground, the return value is nonzero.
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool SetForegroundWindow(IntPtr hWnd);
-
- ///
- /// Retrieves the position of the mouse cursor, in screen coordinates.
- ///
- /// A pointer to a structure that receives the screen coordinates of the cursor.
- /// Returns nonzero if successful or zero otherwise. To get extended error information, call .
- [DllImport(Libraries.User32, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool GetCursorPos([Out] out WinDef.POINT lpPoint);
-
- [DllImport(Libraries.User32)]
- public static extern bool UnionRect(out WinDef.RECT rcDst, ref WinDef.RECT rc1, ref WinDef.RECT rc2);
-
- [DllImport(Libraries.User32, SetLastError = true)]
- public static extern bool IntersectRect(ref WinDef.RECT rcDest, ref WinDef.RECT rc1, ref WinDef.RECT rc2);
-
- [DllImport(Libraries.User32)]
- public static extern IntPtr GetShellWindow();
-
- [DllImport(Libraries.User32, CharSet = CharSet.Unicode)]
- public static extern int MapVirtualKey(int nVirtKey, int nMapType);
-
- [DllImport(Libraries.User32)]
- public static extern int GetSysColor(int nIndex);
-
- [DllImport(Libraries.User32)]
- public static extern IntPtr GetSystemMenu(
- [In] IntPtr hWnd,
- [In] [MarshalAs(UnmanagedType.Bool)] bool bRevert
- );
-
- [DllImport(Libraries.User32, EntryPoint = "EnableMenuItem")]
- private static extern int _EnableMenuItem([In] IntPtr hMenu, [In] SC uIDEnableItem, [In] MF uEnable);
-
- ///
- /// Enables, disables, or grays the specified menu item.
- ///
- /// A handle to the menu.
- /// The menu item to be enabled, disabled, or grayed, as determined by the uEnable parameter.
- /// Controls the interpretation of the uIDEnableItem parameter and indicate whether the menu item is enabled, disabled, or grayed.
- /// The return value specifies the previous state of the menu item (it is either MF_DISABLED, MF_ENABLED, or MF_GRAYED). If the menu item does not exist, the return value is -1 ().
- public static MF EnableMenuItem([In] IntPtr hMenu, [In] SC uIDEnableItem, [In] MF uEnable)
- {
- // Returns the previous state of the menu item, or -1 if the menu item does not exist.
- int iRet = _EnableMenuItem(hMenu, uIDEnableItem, uEnable);
- return (MF)iRet;
- }
-
- [DllImport(Libraries.User32, EntryPoint = "SetWindowRgn", SetLastError = true)]
- private static extern int _SetWindowRgn(
- [In] IntPtr hWnd,
- [In] IntPtr hRgn,
- [In] [MarshalAs(UnmanagedType.Bool)] bool bRedraw
- );
-
- ///
- /// The SetWindowRgn function sets the window region of a window. The window region determines the area within the window where the system permits drawing. The system does not display any portion of a window that lies outside of the window region.
- ///
- /// A handle to the window whose window region is to be set.
- /// A handle to a region. The function sets the window region of the window to this region.
- /// Specifies whether the system redraws the window after setting the window region. If bRedraw is , the system does so; otherwise, it does not.
- /// Native method returned HRESULT.
- public static void SetWindowRgn([In] IntPtr hWnd, [In] IntPtr hRgn, [In] bool bRedraw)
- {
- var err = _SetWindowRgn(hWnd, hRgn, bRedraw);
-
- if (err == 0)
- {
- throw new Win32Exception();
- }
- }
-
- [DllImport(Libraries.User32, EntryPoint = "SetWindowPos", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool _SetWindowPos(
- [In] IntPtr hWnd,
- [In, Optional] IntPtr hWndInsertAfter,
- [In] int x,
- [In] int y,
- [In] int cx,
- [In] int cy,
- [In] SWP uFlags
- );
-
- ///
- /// Changes the size, position, and Z order of a child, pop-up, or top-level window. These windows are ordered according to their appearance on the screen. The topmost window receives the highest rank and is the first window in the Z order.
- ///
- /// A handle to the window.
- /// A handle to the window to precede the positioned window in the Z order.
- /// The new position of the left side of the window, in client coordinates.
- /// The new position of the top of the window, in client coordinates.
- /// The new width of the window, in pixels.
- /// The new height of the window, in pixels.
- /// The window sizing and positioning flags.
- /// If the function succeeds, the return value is nonzero.
- public static bool SetWindowPos(
- [In] IntPtr hWnd,
- [In, Optional] IntPtr hWndInsertAfter,
- [In] int x,
- [In] int y,
- [In] int cx,
- [In] int cy,
- [In] SWP uFlags
- )
- {
- if (!_SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags))
- {
- // If this fails it's never worth taking down the process. Let the caller deal with the error if they want.
- return false;
- }
-
- return true;
- }
-
- ///
- /// Sets the process-default DPI awareness to system-DPI awareness. This is equivalent to calling SetProcessDpiAwarenessContext with a DPI_AWARENESS_CONTEXT value of DPI_AWARENESS_CONTEXT_SYSTEM_AWARE.
- ///
- [DllImport(Libraries.User32)]
- public static extern void SetProcessDPIAware();
-
- ///
- /// Sets various information regarding DWM window attributes.
- ///
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern int SetWindowCompositionAttribute(
- [In] IntPtr hWnd,
- [In, Out] ref WINCOMPATTRDATA data
- );
-
- ///
- /// Sets various information regarding DWM window attributes.
- ///
- [DllImport(Libraries.User32, CharSet = CharSet.Auto)]
- public static extern int GetWindowCompositionAttribute(
- [In] IntPtr hWnd,
- [In, Out] ref WINCOMPATTRDATA data
- );
-
- ///
- /// Returns the dots per inch (dpi) value for the specified window.
- ///
- /// The window that you want to get information about.
- /// The DPI for the window, which depends on the DPI_AWARENESS of the window.
- [DllImport(Libraries.User32, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
- public static extern uint GetDpiForWindow([In] IntPtr hWnd);
-
- ///
- /// Returns the dots per inch (dpi) value for the specified window.
- ///
- /// The window that you want to get information about.
- /// The DPI for the window, which depends on the DPI_AWARENESS of the window.
- [DllImport(Libraries.User32, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
- public static extern uint GetDpiForWindow([In] HandleRef hwnd);
-}
-
-#pragma warning restore SA1300 // Element should begin with upper-case letter
-#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
-#pragma warning restore SA1401 // Fields should be private
diff --git a/src/Wpf.Ui/Interop/UxTheme.cs b/src/Wpf.Ui/Interop/UxTheme.cs
deleted file mode 100644
index 479e01915..000000000
--- a/src/Wpf.Ui/Interop/UxTheme.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-/* This Source Code is partially based on reverse engineering of the Windows Operating System,
- and is intended for use on Windows systems only.
- This Source Code is partially based on the source code provided by the .NET Foundation.
-
- NOTE:
- I split unmanaged code stuff into the NativeMethods library.
- If you have suggestions for the code below, please submit your changes there.
- https://github.com/lepoco/nativemethods */
-
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Wpf.Ui.Interop;
-
-// ReSharper disable IdentifierTypo
-// ReSharper disable InconsistentNaming
-#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
-
-internal static class UxTheme
-{
- ///
- /// Returned by the GetThemeMargins function to define the margins of windows that have visual styles applied.
- ///
- public struct MARGINS
- {
- ///
- /// Width of left border that retains its size.
- ///
- public int cxLeftWidth;
-
- ///
- /// Width of right border that retains its size.
- ///
- public int cxRightWidth;
-
- ///
- /// Height of top border that retains its size.
- ///
- public int cyTopHeight;
-
- ///
- /// Height of bottom border that retains its size.
- ///
- public int cyBottomHeight;
- }
-
- ///
- /// Specifies the type of visual style attribute to set on a window.
- ///
- public enum WINDOWTHEMEATTRIBUTETYPE : uint
- {
- ///
- /// Non-client area window attributes will be set.
- ///
- WTA_NONCLIENT = 1,
- }
-
- ///
- /// WindowThemeNonClientAttributes
- ///
- [Flags]
- public enum WTNCA : uint
- {
- ///
- /// Prevents the window caption from being drawn.
- ///
- NODRAWCAPTION = 0x00000001,
-
- ///
- /// Prevents the system icon from being drawn.
- ///
- NODRAWICON = 0x00000002,
-
- ///
- /// Prevents the system icon menu from appearing.
- ///
- NOSYSMENU = 0x00000004,
-
- ///
- /// Prevents mirroring of the question mark, even in right-to-left (RTL) layout.
- ///
- NOMIRRORHELP = 0x00000008,
-
- ///
- /// A mask that contains all the valid bits.
- ///
- VALIDBITS = NODRAWCAPTION | NODRAWICON | NOMIRRORHELP | NOSYSMENU,
- }
-
- ///
- /// Defines options that are used to set window visual style attributes.
- ///
- [StructLayout(LayoutKind.Explicit)]
- public struct WTA_OPTIONS
- {
- // public static readonly uint Size = (uint)Marshal.SizeOf(typeof(WTA_OPTIONS));
- public const uint Size = 8;
-
- ///
- /// A combination of flags that modify window visual style attributes.
- /// Can be a combination of the WTNCA constants.
- ///
- [FieldOffset(0)]
- public WTNCA dwFlags;
-
- ///
- /// A bitmask that describes how the values specified in dwFlags should be applied.
- /// If the bit corresponding to a value in dwFlags is 0, that flag will be removed.
- /// If the bit is 1, the flag will be added.
- ///
- [FieldOffset(4)]
- public WTNCA dwMask;
- }
-
- ///
- /// Sets attributes to control how visual styles are applied to a specified window.
- ///
- ///
- /// Handle to a window to apply changes to.
- ///
- ///
- /// Value of type WINDOWTHEMEATTRIBUTETYPE that specifies the type of attribute to set.
- /// The value of this parameter determines the type of data that should be passed in the pvAttribute parameter.
- /// Can be the following value:
- /// WTA_NONCLIENT (Specifies non-client related attributes).
- /// pvAttribute must be a pointer of type WTA_OPTIONS.
- ///
- ///
- /// A pointer that specifies attributes to set. Type is determined by the value of the eAttribute value.
- ///
- ///
- /// Specifies the size, in bytes, of the data pointed to by pvAttribute.
- ///
- [DllImport(Libraries.UxTheme, PreserveSig = false)]
- public static extern void SetWindowThemeAttribute(
- [In] IntPtr hWnd,
- [In] WINDOWTHEMEATTRIBUTETYPE eAttribute,
- [In] ref WTA_OPTIONS pvAttribute,
- [In] uint cbAttribute
- );
-
- ///
- /// Tests if a visual style for the current application is active.
- ///
- /// if a visual style is enabled, and windows with visual styles applied should call OpenThemeData to start using theme drawing services.
- [DllImport(Libraries.UxTheme)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool IsThemeActive();
-
- ///
- /// Retrieves the name of the current visual style, and optionally retrieves the color scheme name and size name.
- ///
- /// Pointer to a string that receives the theme path and file name.
- /// Value of type int that contains the maximum number of characters allowed in the theme file name.
- /// Pointer to a string that receives the color scheme name. This parameter may be set to NULL.
- /// Value of type int that contains the maximum number of characters allowed in the color scheme name.
- /// Pointer to a string that receives the size name. This parameter may be set to NULL.
- /// Value of type int that contains the maximum number of characters allowed in the size name.
- /// HRESULT
- [DllImport(Libraries.UxTheme, CharSet = CharSet.Unicode)]
- public static extern int GetCurrentThemeName(
- [Out] StringBuilder pszThemeFileName,
- [In] int dwMaxNameChars,
- [Out] StringBuilder pszColorBuff,
- [In] int cchMaxColorChars,
- [Out] StringBuilder pszSizeBuff,
- [In] int cchMaxSizeChars
- );
-}
-
-#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
diff --git a/src/Wpf.Ui/Interop/WinDef/POINT.cs b/src/Wpf.Ui/Interop/WinDef/POINT.cs
deleted file mode 100644
index 4aa0fd702..000000000
--- a/src/Wpf.Ui/Interop/WinDef/POINT.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-/* This Source Code is partially based on reverse engineering of the Windows Operating System,
- and is intended for use on Windows systems only.
- This Source Code is partially based on the source code provided by the .NET Foundation. */
-
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop.WinDef;
-
-// ReSharper disable InconsistentNaming
-#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
-
-///
-/// The POINT structure defines the x- and y-coordinates of a point.
-///
-[StructLayout(LayoutKind.Sequential)]
-public struct POINT
-{
- ///
- /// Specifies the x-coordinate of the point.
- ///
- public int x;
-
- ///
- /// Specifies the y-coordinate of the point.
- ///
- public int y;
-}
-
-#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
diff --git a/src/Wpf.Ui/Interop/WinDef/POINTL.cs b/src/Wpf.Ui/Interop/WinDef/POINTL.cs
deleted file mode 100644
index d85aa49b5..000000000
--- a/src/Wpf.Ui/Interop/WinDef/POINTL.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-/* This Source Code is partially based on reverse engineering of the Windows Operating System,
- and is intended for use on Windows systems only.
- This Source Code is partially based on the source code provided by the .NET Foundation. */
-
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop.WinDef;
-
-// ReSharper disable InconsistentNaming
-#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
-
-///
-/// The structure defines the x- and y-coordinates of a point.
-///
-[StructLayout(LayoutKind.Sequential)]
-public struct POINTL
-{
- ///
- /// Specifies the x-coordinate of the point.
- ///
- public long x;
-
- ///
- /// Specifies the y-coordinate of the point.
- ///
- public long y;
-}
-
-#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
diff --git a/src/Wpf.Ui/Interop/WinDef/RECT.cs b/src/Wpf.Ui/Interop/WinDef/RECT.cs
deleted file mode 100644
index 57ade04eb..000000000
--- a/src/Wpf.Ui/Interop/WinDef/RECT.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-/* This Source Code is partially based on reverse engineering of the Windows Operating System,
- and is intended for use on Windows systems only.
- This Source Code is partially based on the source code provided by the .NET Foundation. */
-
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop.WinDef;
-
-// ReSharper disable InconsistentNaming
-
-///
-/// The RECT structure defines a rectangle by the coordinates of its upper-left and lower-right corners.
-///
-[StructLayout(LayoutKind.Sequential)]
-public struct RECT
-{
- private int _left;
- private int _top;
- private int _right;
- private int _bottom;
-
- ///
- /// Gets or sets the x-coordinate of the upper-left corner of the rectangle.
- ///
- public int Left
- {
- readonly get { return _left; }
- set { _left = value; }
- }
-
- ///
- /// Gets or sets the x-coordinate of the lower-right corner of the rectangle.
- ///
- public int Right
- {
- readonly get { return _right; }
- set { _right = value; }
- }
-
- ///
- /// Gets or sets the y-coordinate of the upper-left corner of the rectangle.
- ///
- public int Top
- {
- readonly get { return _top; }
- set { _top = value; }
- }
-
- ///
- /// Gets or sets the y-coordinate of the lower-right corner of the rectangle.
- ///
- public int Bottom
- {
- readonly get { return _bottom; }
- set { _bottom = value; }
- }
-
- ///
- /// Gets the width of the rectangle.
- ///
- public readonly int Width
- {
- get { return _right - _left; }
- }
-
- ///
- /// Gets the height of the rectangle.
- ///
- public readonly int Height
- {
- get { return _bottom - _top; }
- }
-
- ///
- /// Gets the position of the rectangle.
- ///
- public POINT Position
- {
- get { return new POINT { x = _left, y = _top }; }
- }
-
- ///
- /// Gets the size of the rectangle.
- ///
- public SIZE Size
- {
- get { return new SIZE { cx = Width, cy = Height }; }
- }
-
- ///
- /// Sets offset of the rectangle.
- ///
- public void Offset(int dx, int dy)
- {
- _left += dx;
- _top += dy;
- _right += dx;
- _bottom += dy;
- }
-
- ///
- /// Combines two RECTs.
- ///
- public static RECT Union(RECT rect1, RECT rect2)
- {
- return new RECT
- {
- Left = Math.Min(rect1.Left, rect2.Left),
- Top = Math.Min(rect1.Top, rect2.Top),
- Right = Math.Max(rect1.Right, rect2.Right),
- Bottom = Math.Max(rect1.Bottom, rect2.Bottom),
- };
- }
-
- ///
- public override readonly bool Equals(object? obj)
- {
- if (obj is not RECT)
- {
- return false;
- }
-
- try
- {
- var rc = (RECT)obj;
-
- return rc._bottom == _bottom && rc._left == _left && rc._right == _right && rc._top == _top;
- }
- catch (InvalidCastException)
- {
- return false;
- }
- }
-
- ///
- public override readonly int GetHashCode()
- {
- return _top.GetHashCode() ^ _bottom.GetHashCode() ^ _left.GetHashCode() ^ _right.GetHashCode();
- }
-
- public static bool operator ==(RECT left, RECT right)
- {
- return left.Equals(right);
- }
-
- public static bool operator !=(RECT left, RECT right)
- {
- return !(left == right);
- }
-}
diff --git a/src/Wpf.Ui/Interop/WinDef/RECTL.cs b/src/Wpf.Ui/Interop/WinDef/RECTL.cs
deleted file mode 100644
index 614f69671..000000000
--- a/src/Wpf.Ui/Interop/WinDef/RECTL.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-/* This Source Code is partially based on reverse engineering of the Windows Operating System,
- and is intended for use on Windows systems only.
- This Source Code is partially based on the source code provided by the .NET Foundation. */
-
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop.WinDef;
-
-// ReSharper disable InconsistentNaming
-
-///
-/// The RECTL structure defines a rectangle by the coordinates of its upper-left and lower-right corners.
-///
-[StructLayout(LayoutKind.Sequential)]
-public struct RECTL
-{
- private long _left;
- private long _top;
- private long _right;
- private long _bottom;
-
- ///
- /// Gets or sets the x-coordinate of the upper-left corner of the rectangle.
- ///
- public long Left
- {
- readonly get { return _left; }
- set { _left = value; }
- }
-
- ///
- /// Gets or sets the x-coordinate of the lower-right corner of the rectangle.
- ///
- public long Right
- {
- readonly get { return _right; }
- set { _right = value; }
- }
-
- ///
- /// Gets or sets the y-coordinate of the upper-left corner of the rectangle.
- ///
- public long Top
- {
- readonly get { return _top; }
- set { _top = value; }
- }
-
- ///
- /// Gets or sets the y-coordinate of the lower-right corner of the rectangle.
- ///
- public long Bottom
- {
- readonly get { return _bottom; }
- set { _bottom = value; }
- }
-
- ///
- /// Gets the width of the rectangle.
- ///
- public readonly long Width
- {
- get { return _right - _left; }
- }
-
- ///
- /// Gets the height of the rectangle.
- ///
- public readonly long Height
- {
- get { return _bottom - _top; }
- }
-
- ///
- /// Gets the position of the rectangle.
- ///
- public POINTL Position
- {
- get { return new POINTL { x = _left, y = _top }; }
- }
-
- ///
- /// Gets the size of the rectangle.
- ///
- public SIZE Size
- {
- get { return new SIZE { cx = Width, cy = Height }; }
- }
-
- ///
- /// Sets offset of the rectangle.
- ///
- public void Offset(int dx, int dy)
- {
- _left += dx;
- _top += dy;
- _right += dx;
- _bottom += dy;
- }
-
- ///
- /// Combines two RECTLs
- ///
- public static RECTL Union(RECTL rect1, RECTL rect2)
- {
- return new RECTL
- {
- Left = Math.Min(rect1.Left, rect2.Left),
- Top = Math.Min(rect1.Top, rect2.Top),
- Right = Math.Max(rect1.Right, rect2.Right),
- Bottom = Math.Max(rect1.Bottom, rect2.Bottom),
- };
- }
-
- ///
- public override readonly bool Equals(object? obj)
- {
- if (obj is not RECTL)
- {
- return false;
- }
-
- try
- {
- var rc = (RECTL)obj;
- return rc._bottom == _bottom && rc._left == _left && rc._right == _right && rc._top == _top;
- }
- catch (InvalidCastException)
- {
- return false;
- }
- }
-
- ///
- public override readonly int GetHashCode()
- {
- return _top.GetHashCode() ^ _bottom.GetHashCode() ^ _left.GetHashCode() ^ _right.GetHashCode();
- }
-
- public static bool operator ==(RECTL left, RECTL right)
- {
- return left.Equals(right);
- }
-
- public static bool operator !=(RECTL left, RECTL right)
- {
- return !(left == right);
- }
-}
diff --git a/src/Wpf.Ui/Interop/WinDef/SIZE.cs b/src/Wpf.Ui/Interop/WinDef/SIZE.cs
deleted file mode 100644
index a0a2aa48d..000000000
--- a/src/Wpf.Ui/Interop/WinDef/SIZE.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-/* This Source Code is partially based on reverse engineering of the Windows Operating System,
- and is intended for use on Windows systems only.
- This Source Code is partially based on the source code provided by the .NET Foundation. */
-
-using System.Runtime.InteropServices;
-
-namespace Wpf.Ui.Interop.WinDef;
-
-// ReSharper disable InconsistentNaming
-#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
-
-///
-/// The SIZE structure defines the width and height of a rectangle.
-///
-[StructLayout(LayoutKind.Sequential)]
-public struct SIZE
-{
- ///
- /// Specifies the rectangle's width. The units depend on which function uses this structure.
- ///
- public long cx;
-
- ///
- /// Specifies the rectangle's height. The units depend on which function uses this structure.
- ///
- public long cy;
-}
-
-#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
diff --git a/src/Wpf.Ui/Markup/Design.cs b/src/Wpf.Ui/Markup/Design.cs
index 3b44d0cd9..d0357ffe8 100644
--- a/src/Wpf.Ui/Markup/Design.cs
+++ b/src/Wpf.Ui/Markup/Design.cs
@@ -20,7 +20,7 @@ namespace Wpf.Ui.Markup;
///
public static class Design
{
- private static readonly string DesignProcessName = "devenv";
+ private static readonly string[] DesignProcesses = ["devenv", "dotnet", "RiderWpfPreviewerLauncher64"];
private static bool? _inDesignMode;
@@ -33,9 +33,11 @@ public static class Design
DependencyPropertyDescriptor
.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(FrameworkElement))
.Metadata.DefaultValue
- || System
- .Diagnostics.Process.GetCurrentProcess()
- .ProcessName.StartsWith(DesignProcessName, StringComparison.Ordinal);
+ || DesignProcesses.Any(process =>
+ System
+ .Diagnostics.Process.GetCurrentProcess()
+ .ProcessName.StartsWith(process, StringComparison.Ordinal)
+ );
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.RegisterAttached(
"Background",
diff --git a/src/Wpf.Ui/Markup/FontIconExtension.cs b/src/Wpf.Ui/Markup/FontIconExtension.cs
index c0e1bf655..8653eb537 100644
--- a/src/Wpf.Ui/Markup/FontIconExtension.cs
+++ b/src/Wpf.Ui/Markup/FontIconExtension.cs
@@ -49,7 +49,7 @@ public FontIconExtension(string glyph)
public override object ProvideValue(IServiceProvider serviceProvider)
{
- FontIcon fontIcon = new() { Glyph = Glyph, FontFamily = FontFamily };
+ FontIcon fontIcon = new() { Glyph = Glyph!, FontFamily = FontFamily };
if (FontSize > 0)
{
diff --git a/src/Wpf.Ui/Markup/ImageIconExtension.cs b/src/Wpf.Ui/Markup/ImageIconExtension.cs
index 69ec1c134..dc5a3c093 100644
--- a/src/Wpf.Ui/Markup/ImageIconExtension.cs
+++ b/src/Wpf.Ui/Markup/ImageIconExtension.cs
@@ -50,7 +50,7 @@ public override object ProvideValue(IServiceProvider serviceProvider)
{
Source = Source,
Width = Width,
- Height = Height
+ Height = Height,
};
return imageIcon;
diff --git a/src/Wpf.Ui/Markup/ThemeResource.cs b/src/Wpf.Ui/Markup/ThemeResource.cs
index 9229d014a..b43b272ae 100644
--- a/src/Wpf.Ui/Markup/ThemeResource.cs
+++ b/src/Wpf.Ui/Markup/ThemeResource.cs
@@ -263,5 +263,5 @@ public enum ThemeResource
///
/// Gradient .
///
- AccentControlElevationBorderBrush
+ AccentControlElevationBorderBrush,
}
diff --git a/src/Wpf.Ui/Markup/ThemesDictionary.cs b/src/Wpf.Ui/Markup/ThemesDictionary.cs
index 07c05bdfe..29ec10bcb 100644
--- a/src/Wpf.Ui/Markup/ThemesDictionary.cs
+++ b/src/Wpf.Ui/Markup/ThemesDictionary.cs
@@ -49,7 +49,7 @@ private void SetSourceBasedOnSelectedTheme(ApplicationTheme? selectedApplication
{
ApplicationTheme.Dark => "Dark",
ApplicationTheme.HighContrast => "HighContrast",
- _ => "Light"
+ _ => "Light",
};
Source = new Uri($"{ApplicationThemeManager.ThemesDictionaryPath}{themeName}.xaml", UriKind.Absolute);
diff --git a/src/Wpf.Ui/NativeMethods.txt b/src/Wpf.Ui/NativeMethods.txt
new file mode 100644
index 000000000..caf4b418b
--- /dev/null
+++ b/src/Wpf.Ui/NativeMethods.txt
@@ -0,0 +1,34 @@
+S_OK
+DwmIsCompositionEnabled
+DwmExtendFrameIntoClientArea
+SetWindowThemeAttribute
+GetDpiForWindow
+IsWindowVisible
+SetWindowLong
+GetWindowLong
+SetWindowRgn
+GetWindowRect
+GetSystemMetrics
+IsWindow
+DwmSetWindowAttribute
+DwmGetWindowAttribute
+ITaskbarList4
+TaskbarList
+DWM_SYSTEMBACKDROP_TYPE
+DWM_WINDOW_CORNER_PREFERENCE
+DWMWA_COLOR_NONE
+WINDOW_STYLE
+WTA_OPTIONS
+WTNCA_*
+WM_*
+HTBOTTOM*
+HTCAPTION
+HTCLOSE
+HTHELP
+HTLEFT*
+HTMAXBUTTON
+HTMINBUTTON
+HTNOWHERE
+HTRIGHT*
+HTSYSMENU
+HTTOP*
\ No newline at end of file
diff --git a/src/Wpf.Ui/Resources/Accent.xaml b/src/Wpf.Ui/Resources/Accent.xaml
index 1cd063de3..cffdd82de 100644
--- a/src/Wpf.Ui/Resources/Accent.xaml
+++ b/src/Wpf.Ui/Resources/Accent.xaml
@@ -8,16 +8,16 @@
- #3379d9
+ #0078d4
- #559ce4
+ #0067c0
- #80b9ee
+ #003e92
- #add8ff
+ #001a68
@@ -31,17 +31,17 @@
-
+
+ Color="{StaticResource SystemAccentColorSecondary}" />
-
+ Color="{StaticResource SystemAccentColorSecondary}" />
+
diff --git a/src/Wpf.Ui/Resources/Fonts/FluentSystemIcons-Filled.ttf b/src/Wpf.Ui/Resources/Fonts/FluentSystemIcons-Filled.ttf
index 21e767087..b7b50993d 100644
Binary files a/src/Wpf.Ui/Resources/Fonts/FluentSystemIcons-Filled.ttf and b/src/Wpf.Ui/Resources/Fonts/FluentSystemIcons-Filled.ttf differ
diff --git a/src/Wpf.Ui/Resources/Fonts/FluentSystemIcons-Regular.ttf b/src/Wpf.Ui/Resources/Fonts/FluentSystemIcons-Regular.ttf
index ff12b0654..fc3c648a1 100644
Binary files a/src/Wpf.Ui/Resources/Fonts/FluentSystemIcons-Regular.ttf and b/src/Wpf.Ui/Resources/Fonts/FluentSystemIcons-Regular.ttf differ
diff --git a/src/Wpf.Ui/Resources/Theme/Dark.xaml b/src/Wpf.Ui/Resources/Theme/Dark.xaml
index 5a8200d85..702cca23b 100644
--- a/src/Wpf.Ui/Resources/Theme/Dark.xaml
+++ b/src/Wpf.Ui/Resources/Theme/Dark.xaml
@@ -102,6 +102,9 @@
#09FFFFFF
#09FFFFFF
+ #171C26
+ #00000000
+
#2C2C2C
@@ -240,7 +243,7 @@
-
+
@@ -257,7 +260,7 @@
-
+
@@ -267,10 +270,13 @@
-
+
+
-
-
+
+
@@ -325,9 +331,9 @@
-
-
-
+
+
+
@@ -335,7 +341,7 @@
-
+
@@ -352,14 +358,16 @@
-
-
-
+
+
+
+
+
-
+
@@ -383,8 +391,10 @@
-
+
+
+
@@ -454,10 +464,10 @@
-
-
-
-
+
+
+
+
@@ -501,8 +511,10 @@
-
+
+
+
@@ -543,7 +555,7 @@
-
+
@@ -565,7 +577,7 @@
-
+
@@ -594,7 +606,7 @@
-
+
@@ -639,15 +651,19 @@
+
-
+
+
-
+
+
+
@@ -675,4 +691,12 @@
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui/Resources/Theme/HC1.xaml b/src/Wpf.Ui/Resources/Theme/HC1.xaml
index 06493c04f..08783909c 100644
--- a/src/Wpf.Ui/Resources/Theme/HC1.xaml
+++ b/src/Wpf.Ui/Resources/Theme/HC1.xaml
@@ -243,11 +243,13 @@
+
+
-
+
@@ -272,7 +274,9 @@
+
+
@@ -391,9 +395,11 @@
-
-
-
+
+
+
+
+
@@ -530,15 +536,19 @@
+
+
+
+
diff --git a/src/Wpf.Ui/Resources/Theme/HC2.xaml b/src/Wpf.Ui/Resources/Theme/HC2.xaml
index dd9bf09bb..46a1e612c 100644
--- a/src/Wpf.Ui/Resources/Theme/HC2.xaml
+++ b/src/Wpf.Ui/Resources/Theme/HC2.xaml
@@ -242,11 +242,13 @@
+
+
-
+
@@ -271,7 +273,9 @@
+
+
@@ -390,9 +394,11 @@
-
-
-
+
+
+
+
+
@@ -529,15 +535,19 @@
+
+
+
+
diff --git a/src/Wpf.Ui/Resources/Theme/HCBlack.xaml b/src/Wpf.Ui/Resources/Theme/HCBlack.xaml
index f1c98689e..aa8044888 100644
--- a/src/Wpf.Ui/Resources/Theme/HCBlack.xaml
+++ b/src/Wpf.Ui/Resources/Theme/HCBlack.xaml
@@ -242,11 +242,13 @@
+
+
-
+
@@ -271,7 +273,9 @@
+
+
@@ -390,9 +394,11 @@
-
-
-
+
+
+
+
+
@@ -529,15 +535,19 @@
+
+
+
+
diff --git a/src/Wpf.Ui/Resources/Theme/HCWhite.xaml b/src/Wpf.Ui/Resources/Theme/HCWhite.xaml
index 60ef60dd7..133fdd886 100644
--- a/src/Wpf.Ui/Resources/Theme/HCWhite.xaml
+++ b/src/Wpf.Ui/Resources/Theme/HCWhite.xaml
@@ -242,11 +242,13 @@
+
+
-
+
@@ -271,7 +273,9 @@
+
+
@@ -390,9 +394,11 @@
-
-
-
+
+
+
+
+
@@ -529,15 +535,19 @@
+
+
+
+
diff --git a/src/Wpf.Ui/Resources/Theme/Light.xaml b/src/Wpf.Ui/Resources/Theme/Light.xaml
index a8288560c..3bbeaa7d4 100644
--- a/src/Wpf.Ui/Resources/Theme/Light.xaml
+++ b/src/Wpf.Ui/Resources/Theme/Light.xaml
@@ -102,6 +102,9 @@
#40FFFFFF
#40FFFFFF
+ #2E4053
+ #CCCCCC
+
#F9F9F9
@@ -241,7 +244,7 @@
-
+
@@ -258,7 +261,7 @@
-
+
@@ -268,10 +271,13 @@
-
+
+
+
+
-
-
+
+
@@ -326,9 +332,9 @@
-
-
-
+
+
+
@@ -336,7 +342,7 @@
-
+
@@ -353,14 +359,16 @@
-
-
-
+
+
+
+
+
-
+
@@ -384,8 +392,10 @@
-
+
+
+
@@ -455,10 +465,10 @@
-
-
-
-
+
+
+
+
@@ -502,8 +512,10 @@
-
+
+
+
@@ -544,7 +556,7 @@
-
+
@@ -566,7 +578,7 @@
-
+
@@ -595,7 +607,7 @@
-
+
@@ -640,15 +652,19 @@
+
-
+
+
-
+
+
+
@@ -676,4 +692,12 @@
+
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui/Resources/Wpf.Ui.xaml b/src/Wpf.Ui/Resources/Wpf.Ui.xaml
index b52f501d3..9ccd69b32 100644
--- a/src/Wpf.Ui/Resources/Wpf.Ui.xaml
+++ b/src/Wpf.Ui/Resources/Wpf.Ui.xaml
@@ -30,7 +30,6 @@
-
diff --git a/src/Wpf.Ui/Taskbar/TaskbarProgressState.cs b/src/Wpf.Ui/Taskbar/TaskbarProgressState.cs
index b63767fcc..0da4da5f4 100644
--- a/src/Wpf.Ui/Taskbar/TaskbarProgressState.cs
+++ b/src/Wpf.Ui/Taskbar/TaskbarProgressState.cs
@@ -34,5 +34,5 @@ public enum TaskBarProgressState
///
/// A yellow progress indicator is displayed in the task bar area.
///
- Paused = 0x8
+ Paused = 0x8,
}
diff --git a/src/Wpf.Ui/ThemeService.cs b/src/Wpf.Ui/ThemeService.cs
index 713cc9440..6092a1c9b 100644
--- a/src/Wpf.Ui/ThemeService.cs
+++ b/src/Wpf.Ui/ThemeService.cs
@@ -35,7 +35,7 @@ public virtual ApplicationTheme GetSystemTheme()
SystemTheme.HC1 => ApplicationTheme.HighContrast,
SystemTheme.HC2 => ApplicationTheme.HighContrast,
SystemTheme.HCWhite => ApplicationTheme.HighContrast,
- _ => ApplicationTheme.Unknown
+ _ => ApplicationTheme.Unknown,
};
}
diff --git a/src/Wpf.Ui/UiApplication.cs b/src/Wpf.Ui/UiApplication.cs
index b12c0b7a9..37f4c5a4f 100644
--- a/src/Wpf.Ui/UiApplication.cs
+++ b/src/Wpf.Ui/UiApplication.cs
@@ -10,6 +10,7 @@ namespace Wpf.Ui;
///
public class UiApplication
{
+ [ThreadStatic]
private static UiApplication? _uiApplication;
private readonly Application? _application;
@@ -132,7 +133,11 @@ private static bool ApplicationHasResources(Application application)
return application
.Resources.MergedDictionaries.Where(e => e.Source is not null)
.Any(e =>
- e.Source.ToString().ToLower().Contains(Appearance.ApplicationThemeManager.LibraryNamespace)
+ e.Source.ToString()
+ .Contains(
+ Appearance.ApplicationThemeManager.LibraryNamespace,
+ StringComparison.OrdinalIgnoreCase
+ )
);
}
}
diff --git a/src/Wpf.Ui/Win32/Utilities.cs b/src/Wpf.Ui/Win32/Utilities.cs
index 97e32c27f..8806c2f1b 100644
--- a/src/Wpf.Ui/Win32/Utilities.cs
+++ b/src/Wpf.Ui/Win32/Utilities.cs
@@ -8,6 +8,8 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
+using Windows.Win32;
+using Windows.Win32.Foundation;
namespace Wpf.Ui.Win32;
@@ -86,9 +88,7 @@ public static bool IsCompositionEnabled
return false;
}
- _ = Interop.Dwmapi.DwmIsCompositionEnabled(out var pfEnabled);
-
- return pfEnabled != 0;
+ return PInvoke.DwmIsCompositionEnabled(out BOOL enabled) == HRESULT.S_OK & enabled;
}
}
diff --git a/src/Wpf.Ui/Wpf.Ui.csproj b/src/Wpf.Ui/Wpf.Ui.csproj
index 5a957f380..1b322d324 100644
--- a/src/Wpf.Ui/Wpf.Ui.csproj
+++ b/src/Wpf.Ui/Wpf.Ui.csproj
@@ -1,11 +1,14 @@
-
+īģŋ
WPF-UI
- net462;net472;net481;net6.0-windows;net8.0-windows
+ net10.0-windows;net9.0-windows;net8.0-windows;net481;net472;net462
true
WPF UI provides the Fluent experience in your known and loved WPF framework. Intuitive design, themes, navigation and new immersive controls. All natively and effortlessly.
true
+ preview
+ true
+ System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute;System.Diagnostics.CodeAnalysis.UnscopedRefAttribute
@@ -51,15 +54,12 @@
-
- all
- build; analyzers
-
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/tests/Wpf.Ui.Gallery.IntegrationTests/Fixtures/TestedApplication.cs b/tests/Wpf.Ui.Gallery.IntegrationTests/Fixtures/TestedApplication.cs
new file mode 100644
index 000000000..27816300d
--- /dev/null
+++ b/tests/Wpf.Ui.Gallery.IntegrationTests/Fixtures/TestedApplication.cs
@@ -0,0 +1,85 @@
+īģŋ// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using FlaUI.Core;
+using FlaUI.Core.Tools;
+using FlaUI.UIA3;
+
+namespace Wpf.Ui.Gallery.IntegrationTests.Fixtures;
+
+///
+/// Class managing the lifecycle of the tested application implementing .
+/// Uses for UI automation.
+///
+public sealed class TestedApplication : IAsyncLifetime
+{
+ private const string ExecutableName = "Wpf.Ui.Gallery.exe";
+
+ private readonly AutomationBase automation = new UIA3Automation();
+
+ private Application? app;
+
+ private Window? mainWindow;
+
+ ///
+ /// Gets the wrapper for an application which should be automated.
+ ///
+ public Application? Application => app;
+
+ ///
+ /// Gets the main window of the applications process.
+ ///
+ public Window? MainWindow => mainWindow ??= app?.GetMainWindow(automation);
+
+ ///
+ public ValueTask InitializeAsync()
+ {
+ if (app is not null)
+ {
+ app.Close();
+ app.Dispose();
+ }
+
+ string path = Path.Combine(
+ Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
+ ExecutableName
+ );
+
+ if (!File.Exists(path))
+ {
+ throw new InvalidOperationException(
+ $"Unable to find the application executable at path \"{path}\"."
+ );
+ }
+
+ app = Application.Launch(path);
+ app.WaitWhileMainHandleIsMissing(TimeSpan.FromMinutes(1));
+
+ return ValueTask.CompletedTask;
+ }
+
+ ///
+ public ValueTask DisposeAsync()
+ {
+ if (app is not null)
+ {
+ if (!app.HasExited)
+ {
+ app.Close();
+ }
+
+ // ReSharper disable once AccessToDisposedClosure
+ Retry.WhileFalse(() => app?.HasExited ?? true, TimeSpan.FromSeconds(2), ignoreException: true);
+
+ app.Dispose();
+
+ app = null;
+ }
+
+ automation?.Dispose();
+
+ return ValueTask.CompletedTask;
+ }
+}
diff --git a/tests/Wpf.Ui.Gallery.IntegrationTests/Fixtures/UiTest.cs b/tests/Wpf.Ui.Gallery.IntegrationTests/Fixtures/UiTest.cs
new file mode 100644
index 000000000..84ebd93d2
--- /dev/null
+++ b/tests/Wpf.Ui.Gallery.IntegrationTests/Fixtures/UiTest.cs
@@ -0,0 +1,92 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using FlaUI.Core;
+using FlaUI.Core.Conditions;
+using FlaUI.Core.Input;
+using FlaUI.Core.WindowsAPI;
+
+namespace Wpf.Ui.Gallery.IntegrationTests.Fixtures;
+
+///
+/// Base class for UI tests implementing to manage lifecycle.
+///
+public abstract class UiTest : IAsyncLifetime
+{
+ private readonly TestedApplication app = new();
+
+ ///
+ /// Gets the wrapper for an application which should be automated.
+ ///
+ internal Application? Application => app.Application;
+
+ ///
+ /// Gets the main window of the applications process.
+ ///
+ internal Window? MainWindow => app.MainWindow;
+
+ ///
+ public ValueTask InitializeAsync() => app.InitializeAsync();
+
+ ///
+ public ValueTask DisposeAsync() => app.DisposeAsync();
+
+ ///
+ /// Finds the first descendant with the given automation id.
+ ///
+ /// The automation id.
+ /// The found element or null if no element was found.
+ protected AutomationElement? FindFirst(string automationId) =>
+ app.MainWindow?.FindFirstDescendant(automationId);
+
+ /// Finds the first descendant with the condition.
+ /// The condition method.
+ /// The found element or null if no element was found.
+ protected AutomationElement? FindFirst(Func conditionFunc) =>
+ app.MainWindow?.FindFirstDescendant(conditionFunc);
+
+ ///
+ /// Creates a Task that will complete after a time delay.
+ ///
+ /// The time delay in seconds.
+ /// A Task that represents the time delay
+ ///
+ /// After the specified time delay, the Task is completed in RanToCompletion state.
+ ///
+ protected Task Wait(int seconds) => Task.Delay(TimeSpan.FromSeconds(seconds));
+
+ ///
+ /// Simulate typing in text. This is slower than setting but raises more events.
+ ///
+ protected void Enter(string value)
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ return;
+ }
+
+ string[] source = value.Replace("\r\n", "\n").Split('\n');
+
+ Keyboard.Type(source[0]);
+
+ foreach (string text in ((IEnumerable)source).Skip(1))
+ {
+ Keyboard.Type(VirtualKeyShort.RETURN);
+ Keyboard.Type(text);
+ }
+
+ global::FlaUI.Core.Input.Wait.UntilInputIsProcessed();
+ }
+
+ ///
+ /// Type the given key.
+ ///
+ protected void Press(VirtualKeyShort virtualKey)
+ {
+ Keyboard.Type(virtualKey);
+
+ global::FlaUI.Core.Input.Wait.UntilInputIsProcessed();
+ }
+}
diff --git a/tests/Wpf.Ui.Gallery.UnitTests/UnitTest1.cs b/tests/Wpf.Ui.Gallery.IntegrationTests/GlobalUsings.cs
similarity index 59%
rename from tests/Wpf.Ui.Gallery.UnitTests/UnitTest1.cs
rename to tests/Wpf.Ui.Gallery.IntegrationTests/GlobalUsings.cs
index dbdc4b17e..c19cb733d 100644
--- a/tests/Wpf.Ui.Gallery.UnitTests/UnitTest1.cs
+++ b/tests/Wpf.Ui.Gallery.IntegrationTests/GlobalUsings.cs
@@ -3,10 +3,8 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
-namespace Wpf.Ui.Gallery.UnitTests;
-
-public class UnitTest1
-{
- [Fact]
- public void Test1() { }
-}
+global using System.Reflection;
+global using AwesomeAssertions;
+global using FlaUI.Core.AutomationElements;
+global using Wpf.Ui.FlaUI;
+global using Wpf.Ui.Gallery.IntegrationTests.Fixtures;
diff --git a/tests/Wpf.Ui.Gallery.IntegrationTests/NavigationTests.cs b/tests/Wpf.Ui.Gallery.IntegrationTests/NavigationTests.cs
new file mode 100644
index 000000000..1b322767f
--- /dev/null
+++ b/tests/Wpf.Ui.Gallery.IntegrationTests/NavigationTests.cs
@@ -0,0 +1,46 @@
+īģŋ// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using FlaUI.Core.Definitions;
+using FlaUI.Core.WindowsAPI;
+
+namespace Wpf.Ui.Gallery.IntegrationTests;
+
+public sealed class NavigationTests : UiTest
+{
+ [Fact]
+ public async Task Settings_ShouldBeAvailable_ThroughAutoSuggestBox()
+ {
+ AutomationElement? autoSuggestBox = FindFirst("NavigationAutoSuggestBox");
+
+ autoSuggestBox
+ .Should()
+ .NotBeNull("because NavigationAutoSuggestBox should be present in the main window");
+
+ autoSuggestBox.As().Enter("Settings");
+
+ await Wait(1);
+
+ FindFirst(c => c.ByText("About"))
+ .Should()
+ .NotBeNull("because Settings page should be displayed after clicking the Settings button");
+ }
+
+ [Fact]
+ public async Task Settings_ShouldBeAvailable_ThroughNavigation()
+ {
+ AutomationElement? settingsButton = FindFirst("NavigationFooterItems")
+ ?.FindFirstDescendant(c => c.ByText("Settings"));
+
+ settingsButton.Should().NotBeNull("because NavigationView should be present in the main window");
+ settingsButton.Click();
+
+ await Wait(1);
+
+ FindFirst(c => c.ByText("About"))
+ .Should()
+ .NotBeNull("because Settings page should be displayed after clicking the Settings button");
+ }
+}
diff --git a/tests/Wpf.Ui.Gallery.IntegrationTests/TitleBarTests.cs b/tests/Wpf.Ui.Gallery.IntegrationTests/TitleBarTests.cs
new file mode 100644
index 000000000..79456cdab
--- /dev/null
+++ b/tests/Wpf.Ui.Gallery.IntegrationTests/TitleBarTests.cs
@@ -0,0 +1,67 @@
+īģŋ// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Windows.Automation;
+using WindowVisualState = FlaUI.Core.Definitions.WindowVisualState;
+
+namespace Wpf.Ui.Gallery.IntegrationTests;
+
+public sealed class TitleBarTests : UiTest
+{
+ [Fact]
+ public async Task CloseButton_ShouldCloseWindow_WhenClicked()
+ {
+ Button? closeButton = FindFirst("TitleBarCloseButton").AsButton();
+
+ closeButton.Should().NotBeNull("because CloseButton should be present in the main window title bar");
+ closeButton.Click(moveMouse: false);
+
+ await Wait(2);
+
+ Application
+ ?.HasExited.Should()
+ .BeTrue("because the main window should be closed after clicking the close button");
+ }
+
+ [Fact]
+ public async Task MinimizeButton_ShouldHideWindow_WhenClicked()
+ {
+ Button? minimizeButton = FindFirst("TitleBarMinimizeButton").AsButton();
+
+ minimizeButton
+ .Should()
+ .NotBeNull("because MinimizeButton should be present in the main window title bar");
+ minimizeButton.Click(moveMouse: false);
+
+ await Wait(2);
+
+ MainWindow
+ .Patterns.Window.Pattern.WindowVisualState.ValueOrDefault.Should()
+ .Be(
+ WindowVisualState.Minimized,
+ "because the main window should be minimized after clicking the minimize button"
+ );
+ }
+
+ [Fact]
+ public async Task MaximizeButton_ShouldExpandWindow_WhenClicked()
+ {
+ Button? maximizeButton = FindFirst("TitleBarMaximizeButton").AsButton();
+
+ maximizeButton
+ .Should()
+ .NotBeNull("because MaximizeButton should be present in the main window title bar");
+ maximizeButton.Click(moveMouse: false);
+
+ await Wait(2);
+
+ MainWindow
+ .Patterns.Window.Pattern.WindowVisualState.ValueOrDefault.Should()
+ .Be(
+ WindowVisualState.Maximized,
+ "because the main window should be maximized after clicking the maximize button"
+ );
+ }
+}
diff --git a/tests/Wpf.Ui.Gallery.IntegrationTests/WindowTests.cs b/tests/Wpf.Ui.Gallery.IntegrationTests/WindowTests.cs
new file mode 100644
index 000000000..b27c75411
--- /dev/null
+++ b/tests/Wpf.Ui.Gallery.IntegrationTests/WindowTests.cs
@@ -0,0 +1,17 @@
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+namespace Wpf.Ui.Gallery.IntegrationTests;
+
+public sealed class WindowTests() : UiTest
+{
+ [Fact]
+ public void WindowTitle_ShouldMatchPredefinedOne()
+ {
+ string? title = MainWindow?.Title;
+
+ title.Should().Be("WPF UI Gallery", "because the main window title should match the predefined one");
+ }
+}
diff --git a/tests/Wpf.Ui.Gallery.IntegrationTests/Wpf.Ui.Gallery.IntegrationTests.csproj b/tests/Wpf.Ui.Gallery.IntegrationTests/Wpf.Ui.Gallery.IntegrationTests.csproj
new file mode 100644
index 000000000..7956d330c
--- /dev/null
+++ b/tests/Wpf.Ui.Gallery.IntegrationTests/Wpf.Ui.Gallery.IntegrationTests.csproj
@@ -0,0 +1,39 @@
+īģŋ
+
+
+ net10.0-windows10.0.26100.0
+ enable
+ Exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
diff --git a/tests/Wpf.Ui.Gallery.IntegrationTests/xunit.runner.json b/tests/Wpf.Ui.Gallery.IntegrationTests/xunit.runner.json
new file mode 100644
index 000000000..2b64621b3
--- /dev/null
+++ b/tests/Wpf.Ui.Gallery.IntegrationTests/xunit.runner.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
+ "culture": "invariant",
+ "parallelizeTestCollections": false,
+ "diagnosticMessages": true
+}
diff --git a/tests/Wpf.Ui.Gallery.UnitTests/Wpf.Ui.Gallery.UnitTests.csproj b/tests/Wpf.Ui.Gallery.UnitTests/Wpf.Ui.Gallery.UnitTests.csproj
deleted file mode 100644
index 91abfb142..000000000
--- a/tests/Wpf.Ui.Gallery.UnitTests/Wpf.Ui.Gallery.UnitTests.csproj
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
- net8.0-windows10.0.22621.0
- false
-
-
-
-
-
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
-
-
-
-
-
-
-
diff --git a/tests/Wpf.Ui.UnitTests/Wpf.Ui.UnitTests.csproj b/tests/Wpf.Ui.UnitTests/Wpf.Ui.UnitTests.csproj
index 26408624f..efa518b76 100644
--- a/tests/Wpf.Ui.UnitTests/Wpf.Ui.UnitTests.csproj
+++ b/tests/Wpf.Ui.UnitTests/Wpf.Ui.UnitTests.csproj
@@ -1,7 +1,7 @@
- net7.0-windows
+ net10.0-windows
false