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/.csharpierrc b/.csharpierrc new file mode 100644 index 000000000..c295ad9e4 --- /dev/null +++ b/.csharpierrc @@ -0,0 +1,10 @@ +{ + "printWidth": 110, + "useTabs": false, + "tabWidth": 4, + "preprocessorSymbolSets": [ + "", + "DEBUG", + "DEBUG,CODE_STYLE" + ] +} 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 new file mode 100644 index 000000000..833e151fa --- /dev/null +++ b/.editorconfig @@ -0,0 +1,418 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# All files +[*] + +#### Core EditorConfig Options #### + +# Encoding +charset = utf-8 + +# Indentation and spacing +tab_width = 4 +indent_size = 4 +indent_style = space + +# New line preferences +end_of_line = unset +insert_final_newline = false + +#### Build files #### + +# Solution files +[*.{sln,slnx}] +tab_width = 4 +indent_size = 4 +indent_style = tab + +# Configuration files +[*.{json,xml,yml,config,runsettings}] +indent_size = 2 + +# MSBuild files +[*.{slnf,props,targets,projitems,csproj,shproj}] +indent_size = 2 + +#### Source files #### + +# Markdown files +[*.md] +indent_size = 2 +insert_final_newline = true + +# C# files +[*.cs] + +#### File Header Template #### +file_header_template = This Source Code Form is subject to the terms of the MIT License.\nIf a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.\nCopyright (C) Leszek Pomianowski and WPF UI Contributors.\nAll Rights Reserved. + +#### .NET Coding Conventions #### + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_property = false:silent + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:warning +dotnet_style_predefined_type_for_member_access = true:warning + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences (set to silent until https://github.com/dotnet/roslyn/issues/52904 is resolved) +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +# Code block preferences +dotnet_style_allow_multiple_blank_lines_experimental = false:warning +dotnet_style_allow_statement_immediately_after_block_experimental = false:warning + +# Expression-level preferences +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:silent +csharp_style_throw_expression = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning + +# Field preferences +dotnet_style_readonly_field = true:warning + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false:warning +csharp_style_var_for_built_in_types = false:none +csharp_style_var_when_type_is_apparent = false:none + +# Expression-bodied members +csharp_style_expression_bodied_accessors = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = false:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = false:silent + +# Pattern matching preferences +csharp_style_prefer_pattern_matching = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async + +# Code-block preferences +csharp_prefer_braces = true:suggestion +csharp_using_directive_placement = outside_namespace:warning +csharp_style_namespace_declarations = file_scoped:warning +csharp_style_unused_value_assignment_preference = discard_variable:warning +csharp_style_unused_value_expression_statement_preference = discard_variable:warning +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:warning + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_prefer_static_local_function = true:warning +csharp_style_pattern_local_over_anonymous_function = true:warning + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = false +csharp_indent_labels = no_change +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +# Naming Symbols + +# constant_fields - Define constant fields +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.required_modifiers = const +# non_private_readonly_fields - Define public, internal and protected readonly fields +dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, internal, protected +dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly +# static_readonly_fields - Define static and readonly fields +dotnet_naming_symbols.static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.static_readonly_fields.required_modifiers = static, readonly +# private_readonly_fields - Define private readonly fields +dotnet_naming_symbols.private_readonly_fields.applicable_accessibilities = private +dotnet_naming_symbols.private_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.private_readonly_fields.required_modifiers = readonly +# public_internal_fields - Define public and internal fields +dotnet_naming_symbols.public_internal_protected_fields.applicable_accessibilities = public, internal, protected +dotnet_naming_symbols.public_internal_protected_fields.applicable_kinds = field +# private_protected_fields - Define private and protected fields +dotnet_naming_symbols.private_protected_fields.applicable_accessibilities = private, protected +dotnet_naming_symbols.private_protected_fields.applicable_kinds = field +# public_symbols - Define any public symbol +dotnet_naming_symbols.public_symbols.applicable_accessibilities = public, internal, protected, protected_internal +dotnet_naming_symbols.public_symbols.applicable_kinds = method, property, event, delegate +# parameters - Defines any parameter +dotnet_naming_symbols.parameters.applicable_kinds = parameter +# non_interface_types - Defines class, struct, enum and delegate types +dotnet_naming_symbols.non_interface_types.applicable_kinds = class, struct, enum, delegate +# interface_types - Defines interfaces +dotnet_naming_symbols.interface_types.applicable_kinds = interface + +# Naming Styles + +# camel_case - Define the camelCase style +dotnet_naming_style.camel_case.capitalization = camel_case +# pascal_case - Define the Pascal_case style +dotnet_naming_style.pascal_case.capitalization = pascal_case +# first_upper - The first character must start with an upper-case character +dotnet_naming_style.first_upper.capitalization = first_word_upper +# prefix_interface_interface_with_i - Interfaces must be PascalCase and the first character of an interface must be an 'I' +dotnet_naming_style.prefix_interface_interface_with_i.capitalization = pascal_case +dotnet_naming_style.prefix_interface_interface_with_i.required_prefix = I + +# Naming Rules + +# Async +dotnet_naming_rule.async_methods_end_in_async.severity = silent +dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods +dotnet_naming_rule.async_methods_end_in_async.style = end_in_async + +dotnet_naming_symbols.any_async_methods.applicable_kinds = method +dotnet_naming_symbols.any_async_methods.applicable_accessibilities = * +dotnet_naming_symbols.any_async_methods.required_modifiers = async + +dotnet_naming_style.end_in_async.required_suffix = Async +dotnet_naming_style.end_in_async.capitalization = pascal_case + +# Constant fields must be PascalCase +dotnet_naming_rule.constant_fields_must_be_pascal_case.severity = silent +dotnet_naming_rule.constant_fields_must_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_must_be_pascal_case.style = pascal_case +# Public, internal and protected readonly fields must be PascalCase +dotnet_naming_rule.non_private_readonly_fields_must_be_pascal_case.severity = silent +dotnet_naming_rule.non_private_readonly_fields_must_be_pascal_case.symbols = non_private_readonly_fields +dotnet_naming_rule.non_private_readonly_fields_must_be_pascal_case.style = pascal_case +# Static readonly fields must be PascalCase +dotnet_naming_rule.static_readonly_fields_must_be_pascal_case.severity = silent +dotnet_naming_rule.static_readonly_fields_must_be_pascal_case.symbols = static_readonly_fields +dotnet_naming_rule.static_readonly_fields_must_be_pascal_case.style = pascal_case +# Private readonly fields must be camelCase +dotnet_naming_rule.private_readonly_fields_must_be_camel_case.severity = silent +dotnet_naming_rule.private_readonly_fields_must_be_camel_case.symbols = private_readonly_fields +dotnet_naming_rule.private_readonly_fields_must_be_camel_case.style = camel_case +# Public and internal fields must be PascalCase +dotnet_naming_rule.public_internal_protected_fields_must_be_pascal_case.severity = silent +dotnet_naming_rule.public_internal_protected_fields_must_be_pascal_case.symbols = public_internal_protected_fields +dotnet_naming_rule.public_internal_protected_fields_must_be_pascal_case.style = pascal_case +# Private and protected fields must be camelCase +dotnet_naming_rule.private_fields_must_be_camel_case.severity = silent +dotnet_naming_rule.private_fields_must_be_camel_case.symbols = private_protected_fields +dotnet_naming_rule.private_fields_must_be_camel_case.style = prefix_private_field_with_underscore +# Public members must be capitalized +dotnet_naming_rule.public_members_must_be_capitalized.severity = silent +dotnet_naming_rule.public_members_must_be_capitalized.symbols = public_symbols +dotnet_naming_rule.public_members_must_be_capitalized.style = first_upper +# Parameters must be camelCase +dotnet_naming_rule.parameters_must_be_camel_case.severity = silent +dotnet_naming_rule.parameters_must_be_camel_case.symbols = parameters +dotnet_naming_rule.parameters_must_be_camel_case.style = camel_case +# Class, struct, enum and delegates must be PascalCase +dotnet_naming_rule.non_interface_types_must_be_pascal_case.severity = silent +dotnet_naming_rule.non_interface_types_must_be_pascal_case.symbols = non_interface_types +dotnet_naming_rule.non_interface_types_must_be_pascal_case.style = pascal_case +# Interfaces must be PascalCase and start with an 'I' +dotnet_naming_rule.interface_types_must_be_prefixed_with_i.severity = silent +dotnet_naming_rule.interface_types_must_be_prefixed_with_i.symbols = interface_types +dotnet_naming_rule.interface_types_must_be_prefixed_with_i.style = prefix_interface_interface_with_i +# prefix_private_field_with_underscore - Private fields must be prefixed with _ +dotnet_naming_style.prefix_private_field_with_underscore.capitalization = camel_case +dotnet_naming_style.prefix_private_field_with_underscore.required_prefix = _ + +# .NET Code Analysis + +dotnet_diagnostic.CA1001.severity = warning +dotnet_diagnostic.CA1009.severity = warning +dotnet_diagnostic.CA1016.severity = warning +dotnet_diagnostic.CA1033.severity = warning +dotnet_diagnostic.CA1049.severity = warning +dotnet_diagnostic.CA1060.severity = warning +dotnet_diagnostic.CA1061.severity = warning +dotnet_diagnostic.CA1063.severity = warning +dotnet_diagnostic.CA1065.severity = warning +dotnet_diagnostic.CA1301.severity = warning +dotnet_diagnostic.CA1400.severity = warning +dotnet_diagnostic.CA1401.severity = warning +dotnet_diagnostic.CA1403.severity = warning +dotnet_diagnostic.CA1404.severity = warning +dotnet_diagnostic.CA1405.severity = warning +dotnet_diagnostic.CA1410.severity = warning +dotnet_diagnostic.CA1415.severity = warning +dotnet_diagnostic.CA1821.severity = warning +dotnet_diagnostic.CA1900.severity = warning +dotnet_diagnostic.CA1901.severity = warning +dotnet_diagnostic.CA2002.severity = warning +dotnet_diagnostic.CA2100.severity = warning +dotnet_diagnostic.CA2101.severity = warning +dotnet_diagnostic.CA2108.severity = warning +dotnet_diagnostic.CA2111.severity = warning +dotnet_diagnostic.CA2112.severity = warning +dotnet_diagnostic.CA2114.severity = warning +dotnet_diagnostic.CA2116.severity = warning +dotnet_diagnostic.CA2117.severity = warning +dotnet_diagnostic.CA2122.severity = warning +dotnet_diagnostic.CA2123.severity = warning +dotnet_diagnostic.CA2124.severity = warning +dotnet_diagnostic.CA2126.severity = warning +dotnet_diagnostic.CA2131.severity = warning +dotnet_diagnostic.CA2132.severity = warning +dotnet_diagnostic.CA2133.severity = warning +dotnet_diagnostic.CA2134.severity = warning +dotnet_diagnostic.CA2137.severity = warning +dotnet_diagnostic.CA2138.severity = warning +dotnet_diagnostic.CA2140.severity = warning +dotnet_diagnostic.CA2141.severity = warning +dotnet_diagnostic.CA2146.severity = warning +dotnet_diagnostic.CA2147.severity = warning +dotnet_diagnostic.CA2149.severity = warning +dotnet_diagnostic.CA2200.severity = warning +dotnet_diagnostic.CA2202.severity = warning +dotnet_diagnostic.CA2207.severity = warning +dotnet_diagnostic.CA2212.severity = warning +dotnet_diagnostic.CA2213.severity = warning +dotnet_diagnostic.CA2214.severity = warning +dotnet_diagnostic.CA2216.severity = warning +dotnet_diagnostic.CA2220.severity = warning +dotnet_diagnostic.CA2229.severity = warning +dotnet_diagnostic.CA2231.severity = warning +dotnet_diagnostic.CA2232.severity = warning +dotnet_diagnostic.CA2235.severity = warning +dotnet_diagnostic.CA2236.severity = warning +dotnet_diagnostic.CA2237.severity = warning +dotnet_diagnostic.CA2238.severity = warning +dotnet_diagnostic.CA2240.severity = warning +dotnet_diagnostic.CA2241.severity = warning +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()!" +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 + +# Hide warnings when accessing properties without "this". +dotnet_diagnostic.SA1101.severity = none +dotnet_diagnostic.SA1118.severity = none +dotnet_diagnostic.SA1200.severity = none +dotnet_diagnostic.SA1201.severity = none +dotnet_diagnostic.SA1202.severity = none +dotnet_diagnostic.SA1309.severity = none +dotnet_diagnostic.SA1310.severity = none + +# Hide warnings for record parameters. +dotnet_diagnostic.SA1313.severity = none + +# TypeParameterNamesMustBeginWithT: We do have a few templates that don't start with T. We need to double check that changing this is not a breaking change. If not, we can re-enable this. +dotnet_diagnostic.SA1314.severity = none + +# UseTrailingCommasInMultiLineInitializers: This would also mean a lot of changes at the end of all multiline initializers. It's also debatable if we want this or not. +dotnet_diagnostic.SA1413.severity = none + +dotnet_diagnostic.SA1600.severity = none +dotnet_diagnostic.SA1602.severity = none +dotnet_diagnostic.SA1611.severity = none + +# DocumentationTextMustEndWithAPeriod: Let's enable this rule back when we shift to WinUI3 (v8.x). If we do it now, it would mean more than 400 file changes. +dotnet_diagnostic.SA1629.severity = none + +dotnet_diagnostic.SA1633.severity = none +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 +dotnet_diagnostic.SA1010.severity = none # Opening square brackets should not be preceded by a space + # conflicts with collection expressions and IDE0028 + +# Suppress some ValueConverter warnings +dotnet_diagnostic.WPF0073.severity = none # Add ValueConversion attribute (unknown types) +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 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 2117c2ac6..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/dependabot.yml b/.github/dependabot.yml index 405d992e5..2f507b710 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,60 +11,14 @@ updates: target-branch: "development" directory: "/" schedule: - interval: "daily" + interval: "daily" labels: - - "Actions" - - # Maintain dependencies for nuget - - package-ecosystem: "nuget" - target-branch: "development" - directory: "src/Wpf.Ui" - schedule: - interval: "daily" - labels: - - "NuGet" - + - "Actions" # Maintain dependencies for nuget - package-ecosystem: "nuget" target-branch: "development" - directory: "src/Wpf.Ui.Demo/" - schedule: - interval: "daily" - labels: - - "NuGet" - - # Maintain dependencies for nuget - - package-ecosystem: "nuget" - target-branch: "development" - directory: "src/Wpf.Ui.SimpleDemo/" - schedule: - interval: "daily" - labels: - - "NuGet" - - # Maintain dependencies for nuget - - package-ecosystem: "nuget" - target-branch: "development" - directory: "src/Wpf.Ui.FontMapper/" - schedule: - interval: "daily" - labels: - - "NuGet" - - # Maintain dependencies for nuget - - package-ecosystem: "nuget" - target-branch: "development" - directory: "src/Wpf.Ui.Extension/Wpf.Ui.Extension/" - schedule: - interval: "daily" - labels: - - "NuGet" - - # Maintain dependencies for nuget - - package-ecosystem: "npm" - target-branch: "development" - directory: "branding/" + directory: "src" schedule: - interval: "daily" + interval: "daily" labels: - - "icons" + - "NuGet" diff --git a/.github/labeler.yml b/.github/labeler.yml index 56acb887f..fe74caf9b 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,29 +1,61 @@ ---- +release: + - base-branch: 'main' + PR: - - "*" + - base-branch: [ 'main', 'development' ] github_actions: - - .github/workflows/* +- changed-files: + - any-glob-to-any-file: '.github/workflows/**' documentation: - - docs/* +- changed-files: + - any-glob-to-any-file: 'docs/**' + +dotnet: +- changed-files: + - any-glob-to-any-file: '**/*.cs' update: - - src/Directory.Build.props +- changed-files: + - any-glob-to-any-file: 'src/Directory.Build.props' -controls: - - src/Wpf.Ui/Controls/* +NuGet: +- changed-files: + - any-glob-to-any-file: 'src/Directory.Packages.props' + +dependencies: +- changed-files: + - any-glob-to-any-file: [ 'src/Directory.Packages.props', 'branding/package.json' ] styles: - - src/Wpf.Ui/Styles/* +- changed-files: + - any-glob-to-any-file: 'src/Wpf.Ui/**/*.xaml' -icons: - - src/Wpf.Ui/Fonts/FluentSystemIcons-Filled.ttf - - src/Wpf.Ui/Fonts/FluentSystemIcons-Regular.ttf +themes: +- changed-files: + - any-glob-to-any-file: 'src/Wpf.Ui/Appearance/**' -dependencies: - - src/Packages.props - - branding/package.json +titlebar: +- changed-files: + - any-glob-to-any-file: 'src/Wpf.Ui/Controls/TitleBar/**' -NuGet: - - src/Packages.props +tray: +- changed-files: + - any-glob-to-any-file: 'src/Wpf.Ui.Tray/**' + +controls: +- changed-files: + - any-glob-to-any-file: 'src/Wpf.Ui/Controls/**' + +navigation: +- changed-files: + - any-glob-to-any-file: 'src/Wpf.Ui/Controls/NavigationView/**' + +gallery: +- changed-files: + - any-glob-to-any-file: 'src/Wpf.Ui.Gallery/**' + +icons: +- changed-files: + - any-glob-to-any-file: [ 'src/Wpf.Ui/Resources/Fonts/**', 'src/Wpf.Ui/Controls/IconSource/*', 'src/Wpf.Ui/Controls/IconElement/*' ] diff --git a/.github/labels.yml b/.github/labels.yml index 396124380..fa1849006 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -1,4 +1,3 @@ ---- - name: "icons" color: "86CBEC" description: "Fonts and icons updates" @@ -47,6 +46,9 @@ - name: ".NET" color: "7121c6" description: "Pull requests that update .NET code." +- name: "dotnet" + color: "7121c6" + description: "Pull requests that update .NET code." - name: "NuGet" color: "004880" description: "Update of the NuGet package." @@ -71,3 +73,4 @@ - name: "wontfix" color: "ffffff" description: "This will not be worked on." + diff --git a/.github/policies/cla.yml b/.github/policies/cla.yml new file mode 100644 index 000000000..dd1a976b9 --- /dev/null +++ b/.github/policies/cla.yml @@ -0,0 +1,25 @@ +name: Contributor License Agreement Policy +description: CLA policy file + +resource: repository + +configuration: + cla: + content: https://raw.githubusercontent.com/lepoco/.github/main/CLA/lepoco.yml + minimalChangeRequired: + files: 1 + codeLines: 1 + bypassUsers: + - azclibot + - azure-pipelines[bot] + - azure-pipelines-bot + - azure-powershell-bot + - azuresdkciprbot + - dependabot[bot] + - dependabot-preview[bot] + - dotnet-bot + - dotnet-corert-bot + - dotnet-docker-bot + - dotnet-maestro[bot] + - dotnet-maestro-bot + - dotnet-winget-bot diff --git a/.github/policies/platformcontext.yml b/.github/policies/platformcontext.yml new file mode 100644 index 000000000..65870e8b2 --- /dev/null +++ b/.github/policies/platformcontext.yml @@ -0,0 +1,10 @@ +name: platform_context +description: The context for GitOps platform, this will drive GitOps specific policies +owner: +resource: repository +where: +configuration: + platformContext: + active: true +onFailure: +onSuccess: diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml deleted file mode 100644 index 8f2ecd4a9..000000000 --- a/.github/workflows/CI.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: DotNet Main - -on: - push: - branches: [main] - - workflow_dispatch: - -jobs: - build: - runs-on: windows-2022 - steps: - - uses: actions/checkout@v3 - - uses: dorny/paths-filter@v2 - id: changes - with: - filters: | - buildprops: - - 'Directory.Build.props' - - - name: Publish - uses: alirezanet/publish-nuget@v3.0.4 - with: - PROJECT_FILE_PATH: src/Wpf.Ui/Wpf.Ui.csproj - VERSION_FILE_PATH: src/Directory.Build.props - NUGET_KEY: ${{secrets.NUGET_API_KEY}} - TAG_COMMIT: false diff --git a/.github/workflows/DV.yml b/.github/workflows/DV.yml deleted file mode 100644 index c383d047e..000000000 --- a/.github/workflows/DV.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: DotNet Development - -on: - pull_request: - branches: [development] - push: - branches: [development] - - workflow_dispatch: - -jobs: - build: - runs-on: windows-2022 - steps: - - uses: actions/checkout@v3 - - uses: microsoft/setup-msbuild@v1.1 - with: - msbuild-architecture: x64 - - uses: nuget/setup-nuget@v1.0.7 - with: - nuget-version: "latest" - - - name: NuGet restore - run: nuget restore src/Wpf.Ui.Demo.sln - - - name: Build - run: msbuild src/Wpf.Ui.sln -p:Configuration=Release -m - - - name: Publish net60 - uses: actions/upload-artifact@v3 - id: publish_net6 - with: - name: WPFUI_DEMO-NET6 - path: | - src/Wpf.Ui.Demo/bin/Release/net6.0-windows10.0.22000.0 diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml deleted file mode 100644 index 356bbb911..000000000 --- a/.github/workflows/labeler.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: "Pull Request Labeler" -on: - - pull_request_target - -jobs: - triage: - permissions: - contents: read - pull-requests: write - runs-on: ubuntu-latest - steps: - - uses: actions/labeler@v4 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml deleted file mode 100644 index 5207ea059..000000000 --- a/.github/workflows/lock.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: "Lock" - -on: - schedule: - - cron: "0 0 * * *" - -jobs: - lock: - runs-on: ubuntu-latest - steps: - - uses: dessant/lock-threads@v3 - with: - # https://github.com/dessant/lock-threads - github-token: ${{ github.token }} - issue-inactive-days: "90" - exclude-issue-created-before: "" - exclude-any-issue-labels: "keep-unlocked, status:awaiting response" - add-issue-labels: "locked-due-to-inactivity" - issue-comment: "" - issue-lock-reason: "resolved" 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 new file mode 100644 index 000000000..ba0368dcf --- /dev/null +++ b/.github/workflows/wpf-ui-cd-docs.yaml @@ -0,0 +1,65 @@ +name: wpf-ui-cd-docs + +on: + push: + branches: [main] + + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + publish: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Use Node.js 18.x + uses: actions/setup-node@v4 + with: + node-version: 18.x + - name: Setup .NET Core SDK 10.x + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.x + + - name: Install docfx + run: dotnet tool update -g docfx + + - name: Install dependencies + run: dotnet restore + + - name: Install template dependencies + run: npm ci + working-directory: docs/templates + + - name: Build docfx template + run: npm run build + working-directory: docs/templates + + - name: docfx Build + run: docfx docs/docfx.json + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/_site/ + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/wpf-ui-cd-extension.yaml b/.github/workflows/wpf-ui-cd-extension.yaml new file mode 100644 index 000000000..8cfe5caa4 --- /dev/null +++ b/.github/workflows/wpf-ui-cd-extension.yaml @@ -0,0 +1,45 @@ +name: wpf-ui-cd-extension + +on: + push: + branches: [main] + paths: + - 'src/Wpf.Ui.Extension**' + + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - 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 }} + + - name: Restore dependencies + 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: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-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 new file mode 100644 index 000000000..6af161ed3 --- /dev/null +++ b/.github/workflows/wpf-ui-cd-nuget.yaml @@ -0,0 +1,63 @@ +name: wpf-ui-cd-nuget + +on: + push: + branches: + - main + - release/* + paths: + - 'src/**' + + workflow_dispatch: + +jobs: + deploy: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - uses: microsoft/setup-msbuild@v2 + with: + msbuild-architecture: x64 + - uses: nuget/setup-nuget@v2 + with: + nuget-api-key: ${{ secrets.NUGET_API_KEY }} + - name: Setup .NET Core SDK 10.x + uses: actions/setup-dotnet@v4 + with: + 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 + + - name: Build + run: dotnet build src\Wpf.Ui\Wpf.Ui.csproj --configuration Release --no-restore -p:SourceLinkEnabled=true + + - 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-labeler.yml b/.github/workflows/wpf-ui-labeler.yml new file mode 100644 index 000000000..13011c317 --- /dev/null +++ b/.github/workflows/wpf-ui-labeler.yml @@ -0,0 +1,15 @@ +name: wpf-ui-labeler + +on: + - pull_request_target + +jobs: + triage: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/wpf-ui-lock.yml b/.github/workflows/wpf-ui-lock.yml new file mode 100644 index 000000000..3cd32bf28 --- /dev/null +++ b/.github/workflows/wpf-ui-lock.yml @@ -0,0 +1,20 @@ +name: wpf-ui-lock + +on: + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: + +permissions: + issues: write + pull-requests: write + discussions: write + +concurrency: + group: lock-threads + +jobs: + action: + runs-on: ubuntu-latest + steps: + - uses: dessant/lock-threads@v5 diff --git a/.github/workflows/wpf-ui-pr-validator.yaml b/.github/workflows/wpf-ui-pr-validator.yaml new file mode 100644 index 000000000..28323af9f --- /dev/null +++ b/.github/workflows/wpf-ui-pr-validator.yaml @@ -0,0 +1,29 @@ +name: wpf-ui-pr-validator + +on: + pull_request: + branches: [main] + + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - uses: microsoft/setup-msbuild@v2 + with: + msbuild-architecture: x64 + - uses: nuget/setup-nuget@v2 + with: + nuget-api-key: ${{ secrets.NUGET_API_KEY }} + - name: Setup .NET Core SDK 10.x + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.x + + - name: Install dependencies + run: dotnet restore + + - name: Build + run: dotnet build src\Wpf.Ui.Gallery\Wpf.Ui.Gallery.csproj --configuration Release --no-restore diff --git a/.gitignore b/.gitignore index 911c07249..30b97c438 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +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 @@ -12,6 +21,12 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# Visual Studio Code files +.vscode + +# IntelliJ IDEA files +.idea + # Mono auto generated files mono_crash.* diff --git a/.vsconfig b/.vsconfig new file mode 100644 index 000000000..41a164770 --- /dev/null +++ b/.vsconfig @@ -0,0 +1,25 @@ +{ + "version": "1.0", + "components": [ + "Microsoft.Component.ClickOnce", + "Microsoft.Component.CodeAnalysis.SDK", + "Microsoft.Component.MSBuild", + "Microsoft.ComponentGroup.ClickOnce.Publish", + "Microsoft.Net.Component.4.6.2.TargetingPack", + "Microsoft.Net.Component.4.7.2.TargetingPack", + "Microsoft.Net.Component.4.8.1.TargetingPack", + "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites", + "Microsoft.Net.ComponentGroup.TargetingPacks.Common", + "Microsoft.NetCore.Component.DevelopmentTools", + "Microsoft.NetCore.Component.Runtime.6.0", + "Microsoft.NetCore.Component.Runtime.7.0", + "Microsoft.NetCore.Component.SDK", + "Microsoft.VisualStudio.Component.ManagedDesktop.Core", + "Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites", + "Microsoft.VisualStudio.Component.NuGet", + "Microsoft.VisualStudio.Component.PortableLibrary", + "Microsoft.VisualStudio.Component.Roslyn.Compiler", + "Microsoft.VisualStudio.Component.Roslyn.LanguageServices", + "Microsoft.VisualStudio.Workload.ManagedDesktop" + ] +} diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..eb2307a9c --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +wpfui.lepo.co \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..463bd58c0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contribution Guidelines + +and as always, todo + +## Prerequisites + +## Code + +### Code style + +## Other general information + +## Acknowledgement diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 000000000..573a58be1 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,107 @@ + + + $(MSBuildThisFileDirectory) + $(RepositoryDirectory)build\ + + + 4.1.0 + 4.1.0 + + + lepo.co + lepo.co + WPF-UI + lepoco;toolkit;wpf;fluent;navigation;controls;design;icons;system;accent;theme;winui + MIT + true + Copyright (C) 2021-2025 Leszek Pomianowski and WPF UI Contributors + https://github.com/lepoco/wpfui + https://github.com/lepoco/wpfui/releases + Icon.png + https://github.com/lepoco/wpfui/main/build/nuget.png + main + git + + + + + + true + moderate + true + false + true + <_SilenceIsAotCompatibleUnsupportedWarning>true + + + true + + + true + 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 + + true + + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + + + + + + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 000000000..fec00b0d4 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,99 @@ + + + true + + + $(CommonTags);.NET + $(CommonTags);$(PackageTags) + $(CommonTags) + + + true + README.md + 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 + + + true + $(RepositoryDirectory)\src\lepo.snk + + + + + + + + + + diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..0008a25de --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LICENSE b/LICENSE index e4d5c8d2e..540d1d913 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2022 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 @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..540d1d913 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +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 +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index aeaa6d385..998a43919 100644 --- a/README.md +++ b/README.md @@ -3,57 +3,51 @@ # WPF UI -[Created with ❤ in Poland by lepo.co](https://dev.lepo.co/) -A simple way to make your application written in WPF keep up with modern design trends. Library changes the base elements like `Page`, `ToggleButton` or `List`, and also includes additional controls like `Navigation`, `NumberBox`, `Dialog` or `Snackbar`. +[Created with ❤ in Poland by Leszek Pomianowski](https://lepo.co/) and [wonderful open-source community](https://github.com/lepoco/wpfui/graphs/contributors). +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. Library changes the base elements like `Page`, `ToggleButton` or `List`, and also includes additional controls like `Navigation`, `NumberBox`, `Dialog` or `Snackbar`. -[![GitHub license](https://img.shields.io/github/license/lepoco/wpfui)](https://github.com/lepoco/wpfui/blob/master/LICENSE) [![Nuget](https://img.shields.io/nuget/v/WPF-UI)](https://www.nuget.org/packages/WPF-UI/) [![Nuget](https://img.shields.io/nuget/dt/WPF-UI?label=nuget-downloads)](https://www.nuget.org/packages/WPF-UI/) [![VS 2022 Downloads](https://img.shields.io/visual-studio-marketplace/i/lepo.WPF-UI?label=vs-2022-downloads)](https://marketplace.visualstudio.com/items?itemName=lepo.WPF-UI) [![Size](https://img.shields.io/github/repo-size/lepoco/wpfui)](https://github.com/lepoco/wpfui) [![Sponsors](https://img.shields.io/github/sponsors/lepoco)](https://github.com/sponsors/lepoco) +[![Discord](https://img.shields.io/discord/1071051348348514375?label=discord)](https://discord.gg/AR9ywDUwGq) [![GitHub license](https://img.shields.io/github/license/lepoco/wpfui)](https://github.com/lepoco/wpfui/blob/master/LICENSE) [![Nuget](https://img.shields.io/nuget/v/WPF-UI)](https://www.nuget.org/packages/WPF-UI/) [![Nuget](https://img.shields.io/nuget/dt/WPF-UI?label=nuget)](https://www.nuget.org/packages/WPF-UI/) + +**Deliver humanitarian aid directly to Ukraine** + ![ua](https://user-images.githubusercontent.com/13592821/184498735-d296feb8-0f9b-45df-bc0d-b7f0b6f580ed.png) -### Deliver humanitarian aid directly to Ukraine. +## 🛟 Support plans -https://bank.gov.ua/en/about/humanitarian-aid-to-ukraine +To ensure you receive the expert guidance you need, we offer a variety of support plans designed to meet the diverse needs of our community. Whether you are looking to modernize your WPF applications or need assistance with our other libraries, our tailored support solutions are here to help. From priority email support to 24/7 dedicated assistance, we provide flexible plans to suit your project requirements. -### Refugees in Poland +[Take a look at the lepo.co support plans](https://lepo.co/support) -Many forms of support for refugees from Ukraine and organizations supporting them are available on the Polish government website -https://pomagamukrainie.gov.pl/chce-pomoc/prywatnie/pomoc-finansowa +## 🤝 Help us keep working on this project -![ua](https://user-images.githubusercontent.com/13592821/184498735-d296feb8-0f9b-45df-bc0d-b7f0b6f580ed.png) +Support the development of WPF UI and other innovative projects by becoming a sponsor on GitHub! Your monthly or one-time contributions help us continue to deliver high-quality, open-source solutions that empower developers worldwide. + +[Sponsor WPF UI on GitHub](https://github.com/sponsors/lepoco) ## 🚀 Getting started For a starter guide see our [documentation](https://wpfui.lepo.co/documentation/). +**WPF UI Gallery** is a free application available in the _Microsoft Store_, with which you can test all functionalities. + + +```powershell +winget install 'WPF UI' +``` + **WPF UI** is delivered via **NuGet** package manager. You can find the package here: -https://www.nuget.org/packages/wpf-ui/ + **Visual Studio** The plugin for **Visual Studio 2022** let you easily create new projects using **WPF UI**. -https://marketplace.visualstudio.com/items?itemName=lepo.wpf-ui - -## 📁 What's included? - -| Name | Framework | -| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Wpf.Ui**
Library that allows you to use all features in your own application | [![NET6](https://img.shields.io/badge/.NET-6.0-red)](https://github.com/lepoco/wpfui/blob/main/src/Wpf.Ui/WPFUI.csproj) [![NET5](https://img.shields.io/badge/.NET-5.0-blue)](https://github.com/lepoco/wpfui/blob/main/src/Wpf.Ui/WPFUI.csproj)
[![NETCore3](https://img.shields.io/badge/.NET%20Core-3.1-brightgreen)](https://github.com/lepoco/wpfui/blob/main/src/Wpf.Ui/WPFUI.csproj)
[![NETFramework48](https://img.shields.io/badge/.NET%20Framework-4.8-orange)](https://github.com/lepoco/wpfui/blob/main/src/Wpf.Ui/WPFUI.csproj)
[![NETFramework47](https://img.shields.io/badge/.NET%20Framework-4.7-orange)](https://github.com/lepoco/wpfui/blob/main/src/Wpf.Ui/WPFUI.csproj)
[![NETFramework461](https://img.shields.io/badge/.NET%20Framework-4.6.1-orange)](https://github.com/lepoco/wpfui/blob/main/src/Wpf.Ui/WPFUI.csproj) | -| **Wpf.Ui.Demo**
An MVVM application written in WPF .NET 6 where you can test the features. | [![NET6win](https://img.shields.io/badge/.NET-6.0--windows-red)](https://github.com/lepoco/wpfui/blob/main/WPFUI.Demo/WPFUI.Demo.csproj) | -| **Wpf.Ui.SimpleDemo**
Simple .NET 6 application with navigation. | [![NET6win](https://img.shields.io/badge/.NET-6.0--windows-red)](https://github.com/lepoco/wpfui/blob/main/WPFUI.Demo/WPFUI.Demo.csproj) | -| **Wpf.Ui.FontMapper**
Console app for generating Fluent System Icons enums. | [![NET6win](https://img.shields.io/badge/.NET-6.0-yellow)](https://github.com/lepoco/wpfui/blob/main/WPFUI.Demo/WPFUI.Demo.csproj) | -| **Wpf.Ui.Extension**
Project for Visual Studio 2022 extension. | [![NET6win](https://img.shields.io/badge/MS%20Build-blue)](https://github.com/lepoco/wpfui/blob/main/WPFUI.Demo/WPFUI.Demo.csproj) | - -## 🏭 Branches - -| Branch | Status | -| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [**WPF UI - Main**](https://github.com/lepoco/wpfui/tree/main) | [![Build status](https://img.shields.io/github/workflow/status/lepoco/wpfui/DotNet%20Main/main)](https://github.com/lepoco/wpfui/actions/workflows/CI.yml) | -| [**WPF UI - Development**](https://github.com/lepoco/wpfui/tree/development) | [![Build status](https://img.shields.io/github/workflow/status/lepoco/wpfui/DotNet%20Development/development)](https://github.com/lepoco/wpfui/actions/workflows/DV.yml) | + ## 📷 Screenshots ![Demo App Sample](https://user-images.githubusercontent.com/13592821/166259110-0fb98120-fe34-4e6d-ab92-9f72ad7113c3.png) -![Text Editor Sample](https://user-images.githubusercontent.com/13592821/165918838-a65cbb86-4fc4-4efb-adb7-e39027fb661f.png) +![Monaco Editor](https://user-images.githubusercontent.com/13592821/258610583-7d71f69d-45b3-4be6-bcb8-8cf6cd60a2ff.png) ![Store App Sample](https://user-images.githubusercontent.com/13592821/165918914-6948fb42-1ee1-4c36-870e-65bb8ffe3c8a.png) @@ -61,33 +55,21 @@ https://marketplace.visualstudio.com/items?itemName=lepo.wpf-ui ![VS2022 Designer Preview](https://user-images.githubusercontent.com/13592821/165919228-0aa3a36c-fb37-4198-835e-53488845226c.png) -## 🏁 Virtualized panels for displaying thousands controls - -![WPF UI virtualized wrap panels](https://user-images.githubusercontent.com/13592821/167254364-bc7d1106-2740-4337-907c-0e0f1ce4c320.png) - ## ❤️ Custom Tray icon and menu in pure WPF ![WPF UI Tray menu in WPF](https://user-images.githubusercontent.com/13592821/166259470-2d48a88e-47ce-4f8f-8f07-c9b110de64a5.png) -## ⚓ Custom Windows 11 SnapLayout available for TitleBar. +## ⚓ Custom Windows 11 SnapLayout available for TitleBar ![WPF UI Snap Layout for WPF](https://user-images.githubusercontent.com/13592821/166259869-e60d37e4-ded4-46bf-80d9-f92c47266f34.png) -## 🕹️ Radiograph - -Radiograph is a computer hardware monitoring app that uses **WPF UI**. - -![Radiograph screenshot](https://user-images.githubusercontent.com/13592821/165918625-6cc72bb1-2617-40fa-a193-60fea0efcd65.png) - -[](https://www.microsoft.com/en-us/p/radiograph/9nh1p86h06cg?activetab=pivot:overviewtab) - ## 📖 Documentation -Documentation can be found at https://wpfui.lepo.co/. We also have a [tutorial](https://wpfui.lepo.co/tutorial/) over there for newcomers. +Documentation can be found at . We also have a [tutorial](#-getting-started) over there for newcomers. ## 🚧 Development -If you want to propose a new functionality or submit a bugfix, create a [Pull Request](https://github.com/lepoco/wpfui/compare/development...development) for the branch [development](https://github.com/lepoco/wpfui/tree/development). +If you want to propose a new functionality or submit a bugfix, create a [Pull Request](https://github.com/lepoco/wpfui/compare/main...main) for the branch [main](https://github.com/lepoco/wpfui/tree/main). ## 📐 How to use? @@ -100,7 +82,7 @@ First, your application needs to load custom styles, add in the **MyApp\App.xaml - + @@ -108,31 +90,38 @@ First, your application needs to load custom styles, add in the **MyApp\App.xaml ``` +If your application does not have **MyApp\App.xaml** file, use `ApplicationThemeManager.Apply(frameworkElement)` to apply/update the theme resource in the `frameworkElement`. + +```C# +public partial class MainWindow +{ + public MainWindow() + { + InitializeComponent(); + ApplicationThemeManager.Apply(this); + } +} +``` + Now you can create fantastic apps, e.g. with one button: ```xml - - - - - + + + + + + + ``` -## Special thanks - -Crafting apps for .NET without the creators of tools like ReSharper or XAML Styler would never be such a fantastic adventure. - -- [🔗 JetBrains ReSharper](https://www.jetbrains.com/resharper/) -- [🔗 XAML Styler](https://github.com/Xavalon/XamlStyler) - ## Microsoft Property Design of the interface, choice of colors and the appearance of the controls were inspired by projects made by Microsoft for Windows 11. -The Wpf.Ui.Demo app includes icons from Shell32 for Windows 11. These icons are the legal property of Microsoft and you may not use them in your own app without permission. They are used here as an example of creating tools for Microsoft systems. +The Wpf.Ui.Gallery app includes icons from _Microsoft WinUI 3 Gallery_ app. They are used here as an example of creating tools for Microsoft systems. ## Segoe Fluent Icons @@ -147,13 +136,6 @@ In the app dictionaries, you can add an alternate path to the font pack://application:,,,/;component/Fonts/#Segoe Fluent Icons ``` -## Compilation - -Use Visual Studio 2022 and invoke the .sln. - -Visual Studio -**WPF UI** is an Open Source project. You are entitled to download and use the freely available Visual Studio Community Edition to build, run or develop for WPF UI. As per the Visual Studio Community Edition license, this applies regardless of whether you are an individual or a corporate user. - ## Code of Conduct This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. diff --git a/Settings.XamlStyler b/Settings.XamlStyler new file mode 100644 index 000000000..7e44ef314 --- /dev/null +++ b/Settings.XamlStyler @@ -0,0 +1,44 @@ +{ + "AttributesTolerance": 2, + "KeepFirstAttributeOnSameLine": false, + "MaxAttributeCharactersPerLine": 0, + "MaxAttributesPerLine": 1, + "NewlineExemptionElements": "RadialGradientBrush, GradientStop, LinearGradientBrush, ScaleTransform, SkewTransform, RotateTransform, TranslateTransform, Trigger, Condition, Setter", + "SeparateByGroups": false, + "AttributeIndentation": 0, + "AttributeIndentationStyle": 1, + "RemoveDesignTimeReferences": false, + "IgnoreDesignTimeReferencePrefix": false, + "EnableAttributeReordering": true, + "AttributeOrderingRuleGroups": [ + "x:Class", + "xmlns, xmlns:x", + "xmlns:*", + "x:Key, Key, x:Name, Name, x:Uid, Uid, Title", + "Grid.Row, Grid.RowSpan, Grid.Column, Grid.ColumnSpan, Canvas.Left, Canvas.Top, Canvas.Right, Canvas.Bottom", + "Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight", + "Margin, Padding, HorizontalAlignment, VerticalAlignment, HorizontalContentAlignment, VerticalContentAlignment, Panel.ZIndex", + "*:*, *", + "PageSource, PageIndex, Offset, Color, TargetName, Property, Value, StartPoint, EndPoint", + "mc:Ignorable, d:IsDataSource, d:LayoutOverrides, d:IsStaticText", + "Storyboard.*, From, To, Duration" + ], + "FirstLineAttributes": "", + "OrderAttributesByName": true, + "PutEndingBracketOnNewLine": false, + "RemoveEndingTagOfEmptyElement": true, + "SpaceBeforeClosingSlash": true, + "RootElementLineBreakRule": 0, + "ReorderVSM": 2, + "ReorderGridChildren": false, + "ReorderCanvasChildren": false, + "ReorderSetters": 0, + "FormatMarkupExtension": true, + "NoNewLineMarkupExtensions": "x:Bind, Binding", + "ThicknessSeparator": 2, + "ThicknessAttributes": "Margin, Padding, BorderThickness, ThumbnailClipMargin", + "FormatOnSave": true, + "CommentPadding": 2, + "IndentSize": 4, + "IndentWithTabs": false +} \ No newline at end of file diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt new file mode 100644 index 000000000..265e0cde3 --- /dev/null +++ b/ThirdPartyNotices.txt @@ -0,0 +1,124 @@ +WPF-UI + +THIRD-PARTY SOFTWARE NOTICES AND INFORMATION +Do Not Translate or Localize + +This project incorporates components from the projects listed below. The original copyright notices and the licenses under which the authors received such components are set forth below. + +1. sbaeumlisberger/VirtualizingWrapPanel version 2.0.6 (https://github.com/sbaeumlisberger/VirtualizingWrapPanel), included in Wpf.Ui. +2. microsoft/fluentui-system-icons version 1.1.242 (https://github.com/microsoft/fluentui-system-icons), included in Wpf.Ui. +3. dotnet/wpf version 8.0 (https://github.com/dotnet/wpf), included in Wpf.Ui. +4. microsoft/microsoft-ui-xaml version 3.0 (https://github.com/microsoft/microsoft-ui-xaml), included in Wpf.Ui. +5. microsoft/segoe-fluent-icons-font version 3.0 (https://learn.microsoft.com/en-us/windows/apps/design/style/segoe-fluent-icons-font), included in Wpf.Ui. + +%% sbaeumlisberger/VirtualizingWrapPanel NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + +Copyright (c) 2019 S. Bäumlisberger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +========================================= +END OF sbaeumlisberger/VirtualizingWrapPanel NOTICES AND INFORMATION + +%% microsoft/fluentui-system-icons NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + +Copyright (c) 2020 Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +========================================= +END OF microsoft/fluentui-system-icons NOTICES AND INFORMATION + +%% dotnet/wpf NOTICES AND INFORMATION BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +========================================= +END OF dotnet/wpf NOTICES AND INFORMATION + +%% microsoft/microsoft-ui-xaml NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE +========================================= +END OF microsoft/microsoft-ui-xaml NOTICES AND INFORMATION + +%% microsoft/segoe-fluent-icons-font NOTICES AND INFORMATION BEGIN HERE +========================================= +You may use the Segoe and icon fonts, or glyphs included in this file (“Software”) solely to design, develop and test your programs that run on a Microsoft Platform, a Microsoft Platform includes but is not limited to any hardware or software product or service branded by trademark, trade dress, copyright or some other recognized means, as a product or service of Microsoft. This license does not grant you the right to distribute or sublicense all or part of the Software to any third party. By using the Software, you agree to these terms. If you do not agree to these terms, do not use the Software. +========================================= +END OF microsoft/segoe-fluent-icons-font NOTICES AND INFORMATION diff --git a/Wpf.Ui.Gallery.slnf b/Wpf.Ui.Gallery.slnf new file mode 100644 index 000000000..e2bd4120d --- /dev/null +++ b/Wpf.Ui.Gallery.slnf @@ -0,0 +1,13 @@ +{ + "solution": { + "path": "Wpf.Ui.sln", + "projects": [ + "src\\Wpf.Ui.Gallery.Package\\Wpf.Ui.Gallery.Package.wapproj", + "src\\Wpf.Ui.Gallery\\Wpf.Ui.Gallery.csproj", + "src\\Wpf.Ui.SyntaxHighlight\\Wpf.Ui.SyntaxHighlight.csproj", + "src\\Wpf.Ui.ToastNotifications\\Wpf.Ui.ToastNotifications.csproj", + "src\\Wpf.Ui.Tray\\Wpf.Ui.Tray.csproj", + "src\\Wpf.Ui\\Wpf.Ui.csproj" + ] + } +} \ No newline at end of file diff --git a/Wpf.Ui.Library.slnf b/Wpf.Ui.Library.slnf new file mode 100644 index 000000000..11b2921d4 --- /dev/null +++ b/Wpf.Ui.Library.slnf @@ -0,0 +1,10 @@ +{ + "solution": { + "path": "Wpf.Ui.sln", + "projects": [ + "src\\Wpf.Ui.ToastNotifications\\Wpf.Ui.ToastNotifications.csproj", + "src\\Wpf.Ui.Tray\\Wpf.Ui.Tray.csproj", + "src\\Wpf.Ui\\Wpf.Ui.csproj" + ] + } +} \ No newline at end of file diff --git a/Wpf.Ui.sln b/Wpf.Ui.sln new file mode 100644 index 000000000..e90969047 --- /dev/null +++ b/Wpf.Ui.sln @@ -0,0 +1,408 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11201.2 d18.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{21DB16AA-40BB-428B-AFE8-DEF4E3F0DC49}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + Directory.Packages.props = Directory.Packages.props + LICENSE = LICENSE + LICENSE.md = LICENSE.md + nuget.config = nuget.config + README.md = README.md + Settings.XamlStyler = Settings.XamlStyler + ThirdPartyNotices.txt = ThirdPartyNotices.txt + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.Gallery", "src\Wpf.Ui.Gallery\Wpf.Ui.Gallery.csproj", "{E55BFB14-9DA6-434A-8153-BFE124D71818}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui", "src\Wpf.Ui\Wpf.Ui.csproj", "{1ADC87D1-8963-4100-845A-18477824718E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.FontMapper", "src\Wpf.Ui.FontMapper\Wpf.Ui.FontMapper.csproj", "{50BAB8DE-6558-4E77-87E5-CD533CBBB72F}" +EndProject +Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Wpf.Ui.Gallery.Package", "src\Wpf.Ui.Gallery.Package\Wpf.Ui.Gallery.Package.wapproj", "{50C713C3-555E-491F-87EE-C806BEC0579F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.UnitTests", "tests\Wpf.Ui.UnitTests\Wpf.Ui.UnitTests.csproj", "{AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{35AC6218-CBEA-4FDA-8CE1-D1EBD6FD8D4A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.Extension", "src\Wpf.Ui.Extension\Wpf.Ui.Extension.csproj", "{1298D974-9D81-4A93-9374-EA6A0E723DEB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.Extension.Template.Compact", "src\Wpf.Ui.Extension.Template.Compact\Wpf.Ui.Extension.Template.Compact.csproj", "{14D7431C-6CFF-4191-BB88-2B8D5F323A30}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.Extension.Template.Blank", "src\Wpf.Ui.Extension.Template.Blank\Wpf.Ui.Extension.Template.Blank.csproj", "{AB3D44B5-9491-487E-A134-9AC5BED2B981}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.Extension.Template.Fluent", "src\Wpf.Ui.Extension.Template.Fluent\Wpf.Ui.Extension.Template.Fluent.csproj", "{4D2706B5-27A9-4542-BD4D-8C22D12D0628}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.ToastNotifications", "src\Wpf.Ui.ToastNotifications\Wpf.Ui.ToastNotifications.csproj", "{3E84FE46-D3FD-4E8A-9208-95E315F16E1F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.Tray", "src\Wpf.Ui.Tray\Wpf.Ui.Tray.csproj", "{073BF126-377B-49CD-838A-E8B779EB4862}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.SyntaxHighlight", "src\Wpf.Ui.SyntaxHighlight\Wpf.Ui.SyntaxHighlight.csproj", "{07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.Abstractions", "src\Wpf.Ui.Abstractions\Wpf.Ui.Abstractions.csproj", "{F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{D7EA6A65-3CB5-4A59-934A-B8402C849107}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.Demo.Console", "samples\Wpf.Ui.Demo.Console\Wpf.Ui.Demo.Console.csproj", "{6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.Demo.Mvvm", "samples\Wpf.Ui.Demo.Mvvm\Wpf.Ui.Demo.Mvvm.csproj", "{5138077E-670E-413D-94D1-0825B6D1201B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.Demo.Simple", "samples\Wpf.Ui.Demo.Simple\Wpf.Ui.Demo.Simple.csproj", "{E37CD05A-EBFC-429D-A550-BEE44119FA9E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.Demo.Dialogs", "samples\Wpf.Ui.Demo.Dialogs\Wpf.Ui.Demo.Dialogs.csproj", "{7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.DependencyInjection", "src\Wpf.Ui.DependencyInjection\Wpf.Ui.DependencyInjection.csproj", "{9C8D6133-9417-43A1-B54F-725009569D71}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.Demo.SetResources.Simple", "samples\Wpf.Ui.Demo.SetResources.Simple\Wpf.Ui.Demo.SetResources.Simple.csproj", "{3B424CF4-09F8-47D3-8420-53D7A1165B9C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.Gallery.IntegrationTests", "tests\Wpf.Ui.Gallery.IntegrationTests\Wpf.Ui.Gallery.IntegrationTests.csproj", "{A396F1D6-55CF-493E-B541-A50B8F29395A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.FlaUI", "src\Wpf.Ui.FlaUI\Wpf.Ui.FlaUI.csproj", "{3E29F5F8-8310-45F4-A648-8F44F32B6472}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|arm64 = Debug|arm64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|arm64 = Release|arm64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Debug|arm64.ActiveCfg = Debug|arm64 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Debug|arm64.Build.0 = Debug|arm64 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Debug|x64.ActiveCfg = Debug|x64 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Debug|x64.Build.0 = Debug|x64 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Debug|x86.ActiveCfg = Debug|x86 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Debug|x86.Build.0 = Debug|x86 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Release|Any CPU.Build.0 = Release|Any CPU + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Release|arm64.ActiveCfg = Release|arm64 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Release|arm64.Build.0 = Release|arm64 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Release|x64.ActiveCfg = Release|x64 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Release|x64.Build.0 = Release|x64 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Release|x86.ActiveCfg = Release|x86 + {E55BFB14-9DA6-434A-8153-BFE124D71818}.Release|x86.Build.0 = Release|x86 + {1ADC87D1-8963-4100-845A-18477824718E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Debug|arm64.ActiveCfg = Debug|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Debug|arm64.Build.0 = Debug|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Debug|x64.ActiveCfg = Debug|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Debug|x64.Build.0 = Debug|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Debug|x86.ActiveCfg = Debug|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Debug|x86.Build.0 = Debug|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Release|Any CPU.Build.0 = Release|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Release|arm64.ActiveCfg = Release|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Release|arm64.Build.0 = Release|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Release|x64.ActiveCfg = Release|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Release|x64.Build.0 = Release|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Release|x86.ActiveCfg = Release|Any CPU + {1ADC87D1-8963-4100-845A-18477824718E}.Release|x86.Build.0 = Release|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Debug|arm64.ActiveCfg = Debug|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Debug|arm64.Build.0 = Debug|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Debug|x64.ActiveCfg = Debug|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Debug|x64.Build.0 = Debug|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Debug|x86.ActiveCfg = Debug|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Debug|x86.Build.0 = Debug|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Release|Any CPU.Build.0 = Release|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Release|arm64.ActiveCfg = Release|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Release|arm64.Build.0 = Release|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Release|x64.ActiveCfg = Release|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Release|x64.Build.0 = Release|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Release|x86.ActiveCfg = Release|Any CPU + {50BAB8DE-6558-4E77-87E5-CD533CBBB72F}.Release|x86.Build.0 = Release|Any CPU + {50C713C3-555E-491F-87EE-C806BEC0579F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50C713C3-555E-491F-87EE-C806BEC0579F}.Debug|arm64.ActiveCfg = Debug|ARM64 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Debug|x64.ActiveCfg = Debug|x64 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Debug|x86.ActiveCfg = Debug|x86 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|arm64.ActiveCfg = Release|ARM64 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|arm64.Build.0 = Release|ARM64 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|arm64.Deploy.0 = Release|ARM64 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|x64.ActiveCfg = Release|x64 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|x64.Build.0 = Release|x64 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|x64.Deploy.0 = Release|x64 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|x86.ActiveCfg = Release|x86 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|x86.Build.0 = Release|x86 + {50C713C3-555E-491F-87EE-C806BEC0579F}.Release|x86.Deploy.0 = Release|x86 + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Debug|arm64.ActiveCfg = Debug|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Debug|arm64.Build.0 = Debug|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Debug|x64.ActiveCfg = Debug|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Debug|x64.Build.0 = Debug|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Debug|x86.ActiveCfg = Debug|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Debug|x86.Build.0 = Debug|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Release|Any CPU.Build.0 = Release|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Release|arm64.ActiveCfg = Release|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Release|arm64.Build.0 = Release|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Release|x64.ActiveCfg = Release|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Release|x64.Build.0 = Release|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Release|x86.ActiveCfg = Release|Any CPU + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C}.Release|x86.Build.0 = Release|Any CPU + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Debug|arm64.ActiveCfg = Debug|arm64 + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Debug|x64.ActiveCfg = Debug|x64 + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Debug|x86.ActiveCfg = Debug|x86 + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Release|Any CPU.Build.0 = Release|Any CPU + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Release|arm64.ActiveCfg = Release|arm64 + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Release|arm64.Build.0 = Release|arm64 + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Release|x64.ActiveCfg = Release|x64 + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Release|x64.Build.0 = Release|x64 + {1298D974-9D81-4A93-9374-EA6A0E723DEB}.Release|x86.ActiveCfg = Release|x86 + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Debug|arm64.ActiveCfg = Debug|arm64 + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Debug|x64.ActiveCfg = Debug|x64 + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Debug|x86.ActiveCfg = Debug|x86 + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Release|Any CPU.Build.0 = Release|Any CPU + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Release|arm64.ActiveCfg = Release|arm64 + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Release|arm64.Build.0 = Release|arm64 + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Release|x64.ActiveCfg = Release|x64 + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Release|x64.Build.0 = Release|x64 + {14D7431C-6CFF-4191-BB88-2B8D5F323A30}.Release|x86.ActiveCfg = Release|x86 + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Debug|arm64.ActiveCfg = Debug|arm64 + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Debug|x64.ActiveCfg = Debug|x64 + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Debug|x86.ActiveCfg = Debug|x86 + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Release|Any CPU.Build.0 = Release|Any CPU + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Release|arm64.ActiveCfg = Release|arm64 + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Release|arm64.Build.0 = Release|arm64 + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Release|x64.ActiveCfg = Release|x64 + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Release|x64.Build.0 = Release|x64 + {AB3D44B5-9491-487E-A134-9AC5BED2B981}.Release|x86.ActiveCfg = Release|x86 + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Debug|arm64.ActiveCfg = Debug|arm64 + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Debug|x64.ActiveCfg = Debug|x64 + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Debug|x86.ActiveCfg = Debug|x86 + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Release|Any CPU.Build.0 = Release|Any CPU + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Release|arm64.ActiveCfg = Release|arm64 + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Release|arm64.Build.0 = Release|arm64 + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Release|x64.ActiveCfg = Release|x64 + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Release|x64.Build.0 = Release|x64 + {4D2706B5-27A9-4542-BD4D-8C22D12D0628}.Release|x86.ActiveCfg = Release|x86 + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Debug|arm64.ActiveCfg = Debug|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Debug|arm64.Build.0 = Debug|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Debug|x64.ActiveCfg = Debug|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Debug|x64.Build.0 = Debug|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Debug|x86.ActiveCfg = Debug|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Debug|x86.Build.0 = Debug|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Release|Any CPU.Build.0 = Release|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Release|arm64.ActiveCfg = Release|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Release|arm64.Build.0 = Release|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Release|x64.ActiveCfg = Release|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Release|x64.Build.0 = Release|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Release|x86.ActiveCfg = Release|Any CPU + {3E84FE46-D3FD-4E8A-9208-95E315F16E1F}.Release|x86.Build.0 = Release|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Debug|Any CPU.Build.0 = Debug|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Debug|arm64.ActiveCfg = Debug|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Debug|arm64.Build.0 = Debug|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Debug|x64.ActiveCfg = Debug|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Debug|x64.Build.0 = Debug|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Debug|x86.ActiveCfg = Debug|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Debug|x86.Build.0 = Debug|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Release|Any CPU.ActiveCfg = Release|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Release|Any CPU.Build.0 = Release|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Release|arm64.ActiveCfg = Release|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Release|arm64.Build.0 = Release|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Release|x64.ActiveCfg = Release|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Release|x64.Build.0 = Release|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Release|x86.ActiveCfg = Release|Any CPU + {073BF126-377B-49CD-838A-E8B779EB4862}.Release|x86.Build.0 = Release|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Debug|arm64.ActiveCfg = Debug|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Debug|arm64.Build.0 = Debug|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Debug|x64.ActiveCfg = Debug|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Debug|x64.Build.0 = Debug|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Debug|x86.ActiveCfg = Debug|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Debug|x86.Build.0 = Debug|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Release|Any CPU.Build.0 = Release|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Release|arm64.ActiveCfg = Release|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Release|arm64.Build.0 = Release|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Release|x64.ActiveCfg = Release|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Release|x64.Build.0 = Release|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Release|x86.ActiveCfg = Release|Any CPU + {07F7A65A-6061-4606-ACA2-F8D1A3D0E19A}.Release|x86.Build.0 = Release|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Debug|arm64.ActiveCfg = Debug|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Debug|arm64.Build.0 = Debug|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Debug|x64.ActiveCfg = Debug|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Debug|x64.Build.0 = Debug|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Debug|x86.Build.0 = Debug|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Release|Any CPU.Build.0 = Release|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Release|arm64.ActiveCfg = Release|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Release|arm64.Build.0 = Release|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Release|x64.ActiveCfg = Release|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Release|x64.Build.0 = Release|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Release|x86.ActiveCfg = Release|Any CPU + {F3A0BD51-2B8C-4E75-A64B-0AED46A22F74}.Release|x86.Build.0 = Release|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Debug|arm64.ActiveCfg = Debug|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Debug|arm64.Build.0 = Debug|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Debug|x64.ActiveCfg = Debug|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Debug|x64.Build.0 = Debug|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Debug|x86.ActiveCfg = Debug|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Debug|x86.Build.0 = Debug|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Release|Any CPU.Build.0 = Release|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Release|arm64.ActiveCfg = Release|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Release|arm64.Build.0 = Release|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Release|x64.ActiveCfg = Release|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Release|x64.Build.0 = Release|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Release|x86.ActiveCfg = Release|Any CPU + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA}.Release|x86.Build.0 = Release|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Debug|arm64.ActiveCfg = Debug|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Debug|arm64.Build.0 = Debug|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Debug|x64.ActiveCfg = Debug|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Debug|x64.Build.0 = Debug|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Debug|x86.ActiveCfg = Debug|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Debug|x86.Build.0 = Debug|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Release|Any CPU.Build.0 = Release|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Release|arm64.ActiveCfg = Release|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Release|arm64.Build.0 = Release|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Release|x64.ActiveCfg = Release|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Release|x64.Build.0 = Release|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Release|x86.ActiveCfg = Release|Any CPU + {5138077E-670E-413D-94D1-0825B6D1201B}.Release|x86.Build.0 = Release|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Debug|arm64.ActiveCfg = Debug|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Debug|arm64.Build.0 = Debug|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Debug|x64.ActiveCfg = Debug|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Debug|x64.Build.0 = Debug|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Debug|x86.ActiveCfg = Debug|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Debug|x86.Build.0 = Debug|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Release|Any CPU.Build.0 = Release|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Release|arm64.ActiveCfg = Release|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Release|arm64.Build.0 = Release|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Release|x64.ActiveCfg = Release|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Release|x64.Build.0 = Release|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Release|x86.ActiveCfg = Release|Any CPU + {E37CD05A-EBFC-429D-A550-BEE44119FA9E}.Release|x86.Build.0 = Release|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Debug|arm64.ActiveCfg = Debug|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Debug|arm64.Build.0 = Debug|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Debug|x64.ActiveCfg = Debug|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Debug|x64.Build.0 = Debug|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Debug|x86.ActiveCfg = Debug|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Debug|x86.Build.0 = Debug|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Release|Any CPU.Build.0 = Release|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Release|arm64.ActiveCfg = Release|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Release|arm64.Build.0 = Release|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Release|x64.ActiveCfg = Release|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Release|x64.Build.0 = Release|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Release|x86.ActiveCfg = Release|Any CPU + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4}.Release|x86.Build.0 = Release|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Debug|arm64.ActiveCfg = Debug|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Debug|arm64.Build.0 = Debug|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Debug|x64.ActiveCfg = Debug|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Debug|x64.Build.0 = Debug|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Debug|x86.ActiveCfg = Debug|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Debug|x86.Build.0 = Debug|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Release|Any CPU.Build.0 = Release|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Release|arm64.ActiveCfg = Release|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Release|arm64.Build.0 = Release|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Release|x64.ActiveCfg = Release|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Release|x64.Build.0 = Release|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Release|x86.ActiveCfg = Release|Any CPU + {9C8D6133-9417-43A1-B54F-725009569D71}.Release|x86.Build.0 = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|arm64.ActiveCfg = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|arm64.Build.0 = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|x64.ActiveCfg = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|x64.Build.0 = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|x86.ActiveCfg = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|x86.Build.0 = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|Any CPU.Build.0 = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|arm64.ActiveCfg = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|arm64.Build.0 = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|x64.ActiveCfg = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|x64.Build.0 = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|x86.ActiveCfg = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|x86.Build.0 = Release|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Debug|arm64.ActiveCfg = Debug|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Debug|arm64.Build.0 = Debug|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Debug|x64.ActiveCfg = Debug|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Debug|x64.Build.0 = Debug|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Debug|x86.ActiveCfg = Debug|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Debug|x86.Build.0 = Debug|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Release|Any CPU.Build.0 = Release|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Release|arm64.ActiveCfg = Release|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Release|arm64.Build.0 = Release|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Release|x64.ActiveCfg = Release|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Release|x64.Build.0 = Release|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Release|x86.ActiveCfg = Release|Any CPU + {A396F1D6-55CF-493E-B541-A50B8F29395A}.Release|x86.Build.0 = Release|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Debug|arm64.ActiveCfg = Debug|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Debug|arm64.Build.0 = Debug|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Debug|x64.ActiveCfg = Debug|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Debug|x64.Build.0 = Debug|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Debug|x86.ActiveCfg = Debug|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Debug|x86.Build.0 = Debug|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Release|Any CPU.Build.0 = Release|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Release|arm64.ActiveCfg = Release|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Release|arm64.Build.0 = Release|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Release|x64.ActiveCfg = Release|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Release|x64.Build.0 = Release|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Release|x86.ActiveCfg = Release|Any CPU + {3E29F5F8-8310-45F4-A648-8F44F32B6472}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {AE87BE68-DFDC-46D8-BC55-DC9D1DD47F4C} = {35AC6218-CBEA-4FDA-8CE1-D1EBD6FD8D4A} + {6F1F6A8D-A530-4C4F-9360-219AC3B43FAA} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} + {5138077E-670E-413D-94D1-0825B6D1201B} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} + {E37CD05A-EBFC-429D-A550-BEE44119FA9E} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} + {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} + {3B424CF4-09F8-47D3-8420-53D7A1165B9C} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} + {A396F1D6-55CF-493E-B541-A50B8F29395A} = {35AC6218-CBEA-4FDA-8CE1-D1EBD6FD8D4A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {234CB3F9-5ADC-433F-BDBD-CB8EA59EB518} + EndGlobalSection +EndGlobal diff --git a/branding/package.json b/branding/package.json deleted file mode 100644 index 5b0827c6a..000000000 --- a/branding/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "homepage": "https://github.com/lepoco/wpfui", - "name": "wpf-ui", - "version": "1.1.0", - "dependencies": { - "@fluentui/react-icons": "2.0.182" - } -} \ No newline at end of file diff --git a/build.cmd b/build.cmd index 242094145..70fd58c7f 100644 --- a/build.cmd +++ b/build.cmd @@ -1,4 +1,4 @@ @echo off -powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0scripts\build_demo.ps1"""" +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0build.ps1"""" @REM powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0scripts\build_extension.ps1"""" -exit /b %ErrorLevel% \ No newline at end of file +exit /b %ErrorLevel% diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 000000000..de2b25257 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,36 @@ +$wingetVersion = & winget --version 2>$null + +if ($wingetVersion -eq $null) { + Write-Output "winget is not installed. Starting installation..." + + Invoke-WebRequest -Uri "https://github.com/microsoft/winget-cli/releases/download/v1.6.3482/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -OutFile "$env:TEMP\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" + + Add-AppxPackage -Path "$env:TEMP\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" + + Write-Output "winget has been installed." +} + +$dotnetVersion = & dotnet --version 2>$null + +if ($dotnetVersion -eq $null) { + Write-Output ".NET SDK is not installed." + + winget install Microsoft.DotNet.SDK.8 +} else { + $majorVersion = $dotnetVersion.Split('.')[0] + + if ($majorVersion -ge 8) { + Write-Output ".NET SDK version is $dotnetVersion, which is 8.0.0 or newer." + } else { + Write-Output ".NET SDK version is $dotnetVersion, which is older than 8.0.0." + + winget install Microsoft.DotNet.SDK.8 + } +} + +if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { + dotnet restore Wpf.Ui.sln /tl + dotnet build src\Wpf.Ui.Gallery\Wpf.Ui.Gallery.csproj --configuration Release --no-restore --verbosity quiet /tl +} else { + Write-Host "Not in the x64 desktop environment." +} diff --git a/src/Wpf.Ui.Demo/Resources/wpfui.png b/build/nuget.png similarity index 100% rename from src/Wpf.Ui.Demo/Resources/wpfui.png rename to build/nuget.png diff --git a/docs/.gitignore b/docs/.gitignore index 4378419e7..f3acf3f4b 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -7,3 +7,5 @@ /**/bin/ /**/obj/ _site +public +/src/ diff --git a/docs/build.ps1 b/docs/build.ps1 deleted file mode 100644 index ea0b8bccb..000000000 --- a/docs/build.ps1 +++ /dev/null @@ -1 +0,0 @@ -docfx .\docfx.json --serve \ No newline at end of file diff --git a/docs/codesnippet/Rtf/Hyperlink/RtfDocumentProcessor.cs b/docs/codesnippet/Rtf/Hyperlink/RtfDocumentProcessor.cs new file mode 100644 index 000000000..3f2425330 --- /dev/null +++ b/docs/codesnippet/Rtf/Hyperlink/RtfDocumentProcessor.cs @@ -0,0 +1,119 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace RtfDocumentProcessors +{ + using System; + using System.Collections.Generic; + using System.Collections.Immutable; + using System.Composition; + using System.IO; + using System.Linq; + using System.Web; + using System.Xml.Linq; + using Microsoft.DocAsCode.Plugins; + using Microsoft.DocAsCode.Utility; + + [Export(typeof(IDocumentProcessor))] + public class RtfDocumentProcessor : IDocumentProcessor + { + [ImportMany(nameof(RtfDocumentProcessor))] + public IEnumerable BuildSteps { get; set; } + + public string Name => nameof(RtfDocumentProcessor); + + public ProcessingPriority GetProcessingPriority(FileAndType file) + { + if ( + file.Type == DocumentType.Article + && ".rtf".Equals(Path.GetExtension(file.File), StringComparison.OrdinalIgnoreCase) + ) + { + return ProcessingPriority.Normal; + } + return ProcessingPriority.NotSupported; + } + + public FileModel Load(FileAndType file, ImmutableDictionary metadata) + { + var content = new Dictionary + { + ["conceptual"] = File.ReadAllText(Path.Combine(file.BaseDir, file.File)), + ["type"] = "Conceptual", + ["path"] = file.File, + }; + return new FileModel(file, content); + } + + #region Save + public SaveResult Save(FileModel model) + { + HashSet linkToFiles = CollectLinksAndFixDocument(model); + + return new SaveResult + { + DocumentType = "Conceptual", + ModelFile = model.File, + LinkToFiles = linkToFiles.ToImmutableArray(), + }; + } + #endregion + + #region CollectLinksAndFixDocument + private static HashSet CollectLinksAndFixDocument(FileModel model) + { + string content = (string)((Dictionary)model.Content)["conceptual"]; + var doc = XDocument.Parse(content); + var links = + from attr in doc.Descendants().Attributes() + where + "href".Equals(attr.Name.LocalName, StringComparison.OrdinalIgnoreCase) + || "src".Equals(attr.Name.LocalName, StringComparison.OrdinalIgnoreCase) + select attr; + var path = (RelativePath)model.File; + var linkToFiles = new HashSet(); + foreach (var link in links) + { + FixLink(link, path, linkToFiles); + } + using (var sw = new StringWriter()) + { + doc.Save(sw); + ((Dictionary)model.Content)["conceptual"] = sw.ToString(); + } + return linkToFiles; + } + #endregion + + #region FixLink + private static void FixLink(XAttribute link, RelativePath filePath, HashSet linkToFiles) + { + string linkFile; + string anchor = null; + if (PathUtility.IsRelativePath(link.Value)) + { + var index = link.Value.IndexOf('#'); + if (index == -1) + { + linkFile = link.Value; + } + else if (index == 0) + { + return; + } + else + { + linkFile = link.Value.Remove(index); + anchor = link.Value.Substring(index); + } + var path = filePath + (RelativePath)linkFile; + var file = (string)path.GetPathFromWorkingFolder(); + link.Value = file + anchor; + linkToFiles.Add(HttpUtility.UrlDecode(file)); + } + } + #endregion + + public void UpdateHref(FileModel model, IDocumentBuildContext context) { } + } +} diff --git a/docs/codesnippet/Rtf/RtfBuildStep.cs b/docs/codesnippet/Rtf/RtfBuildStep.cs new file mode 100644 index 000000000..28b21ebf3 --- /dev/null +++ b/docs/codesnippet/Rtf/RtfBuildStep.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace RtfDocumentProcessors +{ + using System; + using System.Collections.Generic; + using System.Collections.Immutable; + using System.Composition; + using System.Threading.Tasks; + using System.Threading.Tasks.Schedulers; + using MarkupConverter; + using Microsoft.DocAsCode.Plugins; + + [Export(nameof(RtfDocumentProcessor), typeof(IDocumentBuildStep))] + public class RtfBuildStep : IDocumentBuildStep + { + #region Build + private readonly TaskFactory _taskFactory = new TaskFactory(new StaTaskScheduler(1)); + + public void Build(FileModel model, IHostService host) + { + string content = (string)((Dictionary)model.Content)["conceptual"]; + content = _taskFactory.StartNew(() => RtfToHtmlConverter.ConvertRtfToHtml(content)).Result; + ((Dictionary)model.Content)["conceptual"] = content; + } + #endregion + + #region Others + public int BuildOrder => 0; + + public string Name => nameof(RtfBuildStep); + + public void Postbuild(ImmutableList models, IHostService host) { } + + public IEnumerable Prebuild(ImmutableList models, IHostService host) + { + return models; + } + #endregion + } +} diff --git a/docs/codesnippet/Rtf/RtfDocumentProcessor.cs b/docs/codesnippet/Rtf/RtfDocumentProcessor.cs new file mode 100644 index 000000000..35fd8e2ea --- /dev/null +++ b/docs/codesnippet/Rtf/RtfDocumentProcessor.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace RtfDocumentProcessors +{ + using System; + using System.Collections.Generic; + using System.Collections.Immutable; + using System.Composition; + using System.IO; + using Microsoft.DocAsCode.Common; + using Microsoft.DocAsCode.Plugins; + + [Export(typeof(IDocumentProcessor))] + public class RtfDocumentProcessor : IDocumentProcessor + { + #region BuildSteps + [ImportMany(nameof(RtfDocumentProcessor))] + public IEnumerable BuildSteps { get; set; } + #endregion + + #region Name + public string Name => nameof(RtfDocumentProcessor); + #endregion + + #region GetProcessingPriority + public ProcessingPriority GetProcessingPriority(FileAndType file) + { + if ( + file.Type == DocumentType.Article + && ".rtf".Equals(Path.GetExtension(file.File), StringComparison.OrdinalIgnoreCase) + ) + { + return ProcessingPriority.Normal; + } + return ProcessingPriority.NotSupported; + } + #endregion + + #region Load + public FileModel Load(FileAndType file, ImmutableDictionary metadata) + { + var content = new Dictionary + { + ["conceptual"] = File.ReadAllText(Path.Combine(file.BaseDir, file.File)), + ["type"] = "Conceptual", + ["path"] = file.File, + }; + var localPathFromRoot = PathUtility.MakeRelativePath( + EnvironmentContext.BaseDirectory, + EnvironmentContext.FileAbstractLayer.GetPhysicalPath(file.File) + ); + + return new FileModel(file, content) { LocalPathFromRoot = localPathFromRoot }; + } + #endregion + + #region Save + public SaveResult Save(FileModel model) + { + return new SaveResult + { + DocumentType = "Conceptual", + FileWithoutExtension = Path.ChangeExtension(model.File, null), + }; + } + #endregion + + #region UpdateHref + public void UpdateHref(FileModel model, IDocumentBuildContext context) { } + #endregion + } +} diff --git a/docs/docfx.json b/docs/docfx.json index 2329f8dd4..462d9f49d 100644 --- a/docs/docfx.json +++ b/docs/docfx.json @@ -3,14 +3,18 @@ { "src": [ { - "files": ["*.csproj"], - "exclude": ["**/bin/**", "**/obj/**"], - "src": "../src/Wpf.Ui" + "files": [ + "src/Wpf.Ui/*.csproj", + "src/Wpf.Ui.Tray/*.csproj", + "src/Wpf.Ui.Abstractions/*.csproj", + "src/Wpf.Ui.DependencyInjection/*.csproj" + ], + "src": "../" } ], - "dest": "documentation", + "dest": "api", "properties": { - "TargetFramework": "net6.0" + "TargetFramework": "net472" }, "disableGitFeatures": false, "disableDefaultFilter": false @@ -19,45 +23,58 @@ "build": { "content": [ { - "files": ["tutorial/**.md", "tutorial/**/toc.yml", "toc.yml", "*.md"] - }, - { - "files": ["documentation/**.yml", "documentation/index.md"] + "files": [ + "**/*.{md,yml}" + ], + "exclude": [ + "_site/**", + "obj/**" + ] } ], "resource": [ { - "files": ["images/**", "manifest.webmanifest", "robots.txt"] + "files": [ + "**/images/**", + "codesnippet/**", + "manifest.webmanifest", + "robots.txt" + ], + "exclude": [ + "_site/**", + "obj/**" + ] } ], - "overwrite": [ - { - "exclude": ["obj/**", "_site/**"] - } + "xrefService": [ + "https://xref.docs.microsoft.com/query?uid={uid}" + ], + "postProcessors": [ + "ExtractSearchIndex" ], - "dest": "_site", "globalMetadata": { "_appTitle": "WPF UI", "_appName": "WPF UI", "_appFaviconPath": "images/favicon.ico", "_appLogoPath": "images/wpfui.png", - "_appFooter": "", - "_description": "A simple way to make your application written in WPF keep up with modern design trends.", - "_copyrightFooter": "", - "_enableSearch": false, - "_disableSideFilter": false, - "_enableNewTab": true, - "_disableContribution": false, - "_disableBreadcrumb": false + "_appFooter": "Made with docfx, ChatGPT and DeepL | Copyright © 2025 lepo.co" }, + "dest": "_site", + "template": [ + "default", + "templates/wpfui" + ], "globalMetadataFiles": [], "fileMetadataFiles": [], - "template": ["default", "templates/singulinkfx"], - "postProcessors": [], "markdownEngineName": "markdig", "noLangKeyword": false, "keepFileLink": false, "cleanupCacheHistory": false, "disableGitFeatures": false + }, + "sitemap": { + "baseUrl": "https://wpfui.lepo.co", + "priority": 0.1, + "changefreq": "monthly" } } diff --git a/docs/documentation/about-wpf.md b/docs/documentation/about-wpf.md new file mode 100644 index 000000000..1f1e9c01a --- /dev/null +++ b/docs/documentation/about-wpf.md @@ -0,0 +1,19 @@ +# What is WPF + +WPF (Windows Presentation Foundation) is a resolution-independent UI framework for building Windows desktop applications. It provides vector-based graphics, advanced layout, data binding, multimedia, animation, and extensive styling and templating capabilities. + +## .NET Framework vs Modern .NET + +WPF has two implementations: + +**Modern .NET** (.NET 6+): Open-source implementation hosted on GitHub. Provides improved performance, new APIs, side-by-side deployment, and modern tooling. Despite .NET being cross-platform, WPF only runs on Windows. + +**.NET Framework 4**: Legacy Windows-only implementation. Maintained for compatibility with existing applications but receives minimal new features. + +New WPF applications should target modern .NET (.NET 6 or later) to benefit from: + +- Better performance and reduced memory usage +- Regular updates and new features +- Modern C# language versions +- Improved debugging and diagnostics +- Side-by-side deployment without machine-wide installations diff --git a/docs/documentation/accent.md b/docs/documentation/accent.md new file mode 100644 index 000000000..4c35b7eac --- /dev/null +++ b/docs/documentation/accent.md @@ -0,0 +1,211 @@ +# Accent Colors + +Accent colors provide visual emphasis and brand identity in WPF UI applications. The library manages accent color resources that automatically adapt to light and dark themes. + +> [!TIP] +> Use `SystemThemeWatcher.Watch(this)` in your main window constructor to automatically sync accent colors with Windows personalization settings. + +## Apply System Accent + +Use the system's personalization accent color: + +```csharp +using Wpf.Ui.Appearance; + +ApplicationAccentColorManager.ApplySystemAccent(); +``` + +## Apply Theme with Accent + +Apply theme and accent together: + +```csharp +using Wpf.Ui.Appearance; +using Wpf.Ui.Controls; + +ApplicationThemeManager.Apply( + ApplicationTheme.Dark, + WindowBackdropType.Mica, + updateAccent: true // Automatically applies system accent +); +``` + +Available backdrop types: `None`, `Auto`, `Mica`, `Acrylic`, `Tabbed`. + +> [!IMPORTANT] +> Always use `DynamicResource` (not `StaticResource`) for accent color bindings to receive runtime updates when accent changes. + +## Apply Custom Accent + +Set a custom accent color: + +```csharp +ApplicationAccentColorManager.Apply( + Color.FromArgb(0xFF, 0xEE, 0x00, 0xBB), + ApplicationTheme.Dark +); +``` + +Retrieve the Windows colorization color programmatically: + +```csharp +Color colorizationColor = ApplicationAccentColorManager.GetColorizationColor(); +ApplicationAccentColorManager.Apply(colorizationColor, ApplicationTheme.Dark); +``` + +## Accent Color Resources + +WPF UI provides these accent color resources: + +### System Accent Colors + +Base accent colors that update when you call `ApplicationAccentColorManager.Apply()`: + +- `SystemAccentColor` - Primary system accent +- `SystemAccentColorPrimary` - Lighter/darker variant for light/dark themes +- `SystemAccentColorSecondary` - More prominent variant (most commonly used) +- `SystemAccentColorTertiary` - Strongest variant + +```xml + +``` + +> [!TIP] +> `SystemAccentColorSecondary` is the most commonly used variant for interactive elements and provides optimal contrast in both light and dark themes. + +### Accent Text Colors + +For text and interactive elements like links: + +- `AccentTextFillColorPrimaryBrush` - Primary accent text (rest/hover state) +- `AccentTextFillColorSecondaryBrush` - Secondary accent text +- `AccentTextFillColorTertiaryBrush` - Tertiary accent text (pressed state) +- `AccentTextFillColorDisabledBrush` - Disabled accent text + +```xml + +``` + +### Accent Fill Colors + +For button backgrounds and filled surfaces: + +- `AccentFillColorDefaultBrush` - Default accent fill +- `AccentFillColorSecondaryBrush` - Secondary fill (90% opacity) +- `AccentFillColorTertiaryBrush` - Tertiary fill (80% opacity) +- `AccentFillColorDisabledBrush` - Disabled state fill + +```xml +