From 5c18d24395c8ae0f93746da40720789091b15871 Mon Sep 17 00:00:00 2001 From: Damian Suess Date: Mon, 26 Aug 2024 08:48:05 -0400 Subject: [PATCH] Updated Dialog app template to be based on Samples --- Prism.Avalonia.Templates.csproj | 2 +- .../csharp/app-prism-dialog/.editorconfig | 378 ++++++++++++++++++ .../.template.config/template.json | 2 +- templates/csharp/app-prism-dialog/App.axaml | 14 +- .../csharp/app-prism-dialog/App.axaml.cs | 41 +- .../Assets/Prism.Avalonia.png | Bin 12857 -> 0 bytes .../csharp/app-prism-dialog/Assets/logo.ico | Bin 0 -> 16958 bytes templates/csharp/app-prism-dialog/Models/-.- | 0 .../PrismSimpleDialogTemplate.csproj | 29 -- templates/csharp/app-prism-dialog/Program.cs | 34 +- .../csharp/app-prism-dialog/SampleApp.csproj | 26 ++ .../ViewModels/MainWindowViewModel.cs | 83 ++-- .../ViewModels/MessageBoxViewModel.cs | 71 ++++ .../ViewModels/NotificationDialogViewModel.cs | 58 --- .../ViewModels/ViewModelBase.cs | 44 +- .../app-prism-dialog/Views/MainWindow.axaml | 20 +- .../Views/MainWindow.axaml.cs | 10 +- .../Views/MessageBoxView.axaml | 62 +++ .../Views/MessageBoxView.axaml.cs | 13 + .../Views/NotificationDialogView.axaml | 34 -- .../Views/NotificationDialogView.axaml.cs | 13 - .../csharp/app-prism-dialog/app.manifest | 6 +- tests/build-test.ps1 | 5 +- 23 files changed, 650 insertions(+), 295 deletions(-) create mode 100644 templates/csharp/app-prism-dialog/.editorconfig delete mode 100644 templates/csharp/app-prism-dialog/Assets/Prism.Avalonia.png create mode 100644 templates/csharp/app-prism-dialog/Assets/logo.ico delete mode 100644 templates/csharp/app-prism-dialog/Models/-.- delete mode 100644 templates/csharp/app-prism-dialog/PrismSimpleDialogTemplate.csproj create mode 100644 templates/csharp/app-prism-dialog/SampleApp.csproj create mode 100644 templates/csharp/app-prism-dialog/ViewModels/MessageBoxViewModel.cs delete mode 100644 templates/csharp/app-prism-dialog/ViewModels/NotificationDialogViewModel.cs create mode 100644 templates/csharp/app-prism-dialog/Views/MessageBoxView.axaml create mode 100644 templates/csharp/app-prism-dialog/Views/MessageBoxView.axaml.cs delete mode 100644 templates/csharp/app-prism-dialog/Views/NotificationDialogView.axaml delete mode 100644 templates/csharp/app-prism-dialog/Views/NotificationDialogView.axaml.cs diff --git a/Prism.Avalonia.Templates.csproj b/Prism.Avalonia.Templates.csproj index e98b6a2..d27b4ca 100644 --- a/Prism.Avalonia.Templates.csproj +++ b/Prism.Avalonia.Templates.csproj @@ -22,7 +22,7 @@ - + diff --git a/templates/csharp/app-prism-dialog/.editorconfig b/templates/csharp/app-prism-dialog/.editorconfig new file mode 100644 index 0000000..5b51dee --- /dev/null +++ b/templates/csharp/app-prism-dialog/.editorconfig @@ -0,0 +1,378 @@ +# Copyright CURRENT_YEAR COMPANY_NAME +# +# This EditorConfig file provides consistent coding styles and formatting structure based on +# C# standards by Xeno Innovations for your team's projects while preserving your personal defaults. +# +# For more info: +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options +# + +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +[*] +# All generic files should use MSDOS style endings, not Unix (lf) +# end_of_line = crlf +indent_style = space + +[*.{cs,csx}] +indent_style = space +indent_size = 4 +tab_width = 4 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{xml,xaml,axml,axaml}] +indent_style = space +indent_size = 2 +charset = utf-8-bom +trim_trailing_whitespace = true + +[*.json] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.sln] +indent_size = 2 + +# Xml project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +# Xml config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.svg] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +# PList Files +[*.plist] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +# YAML files +[*.{yaml,yml}] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +# Shell script files +[*.sh] +end_of_line = lf +indent_style = space +indent_size = 2 + +# Powershell +[*.{ps1,psd1,psm1}] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.md] +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +# C# Ruleset +[*.{cs,csx}] +# 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 = one_less_than_current +csharp_indent_switch_labels = true + +## Formatting - new line options +### Require braces to be on a new line for (also known as "Allman" style) +### accessors, methods, object_collection, control_blocks, types, properties, lambdas +csharp_new_line_before_open_brace = all +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +## Spaces +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_keywords_in_control_flow_statements = true +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_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_parameter_list_parentheses = false + +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion + +# Organize Usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = true +file_header_template = unset +# file_header_template = Copyright Xeno Innovations, Inc. 2022\nSee the LICENSE file in the project root for more information. + +# this. and Me. preferences +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# Modifier preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_require_accessibility_modifiers = for_non_interface_members +dotnet_style_readonly_field = true + +# Expression-level preferences +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = true +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# Parameter preferences +dotnet_code_quality_unused_parameters = all + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +#dotnet_diagnostic.IDE2000.severity = warning +dotnet_style_allow_multiple_blank_lines_experimental = false:error + +# dotnet_diagnostic.IDE2001.severity = none +csharp_style_allow_embedded_statements_on_same_line_experimental = false + +# dotnet_diagnostic.IDE2002.severity = warning +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false + +# dotnet_diagnostic.IDE2003.severity = error +dotnet_style_allow_statement_immediately_after_block_experimental = false:error + +# Naming Conventions +## Async methods must use "Async" suffix +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_rule.async_methods_end_in_async.severity = error +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.capitalization = pascal_case +dotnet_naming_style.end_in_async.required_prefix = +dotnet_naming_style.end_in_async.required_suffix = Async +dotnet_naming_style.end_in_async.word_separator = + +## private fields must prefix with an underscore +dotnet_naming_rule.private_members_with_underscore.symbols = private_fields +dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore +dotnet_naming_rule.private_members_with_underscore.severity = error +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private +dotnet_naming_style.prefix_underscore.capitalization = camel_case +dotnet_naming_style.prefix_underscore.required_prefix = _ + +## private static fields must use PascalCase (overrides '_' based on SA1311) +dotnet_naming_rule.private_static_field_naming.symbols = private_static_field_naming +dotnet_naming_rule.private_static_field_naming.style = pascal_case_style +dotnet_naming_rule.private_static_field_naming.severity = error +dotnet_naming_symbols.private_static_field_naming.applicable_kinds = field +dotnet_naming_symbols.private_static_field_naming.applicable_accessibilities = private +dotnet_naming_symbols.private_static_field_naming.required_modifiers = static, readonly +dotnet_naming_style.pascal_case_style.capitalization = pascal_case + +## Constant fields must use PascalCase +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = error +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.applicable_accessibilities = * +dotnet_naming_symbols.constant_fields.required_modifiers = const +dotnet_naming_style.pascal_case_style.capitalization = pascal_case + +## Interfaces must have an I suffix +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.severity = error +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = +dotnet_naming_style.begins_with_i.capitalization = pascal_case +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = + +## Types and Non-Field Members must be PascalCase +dotnet_naming_rule.types_should_be_pascal_case.severity = error +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = error +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +## Code Style Rules +# IDE1005: Use conditional delegate call +csharp_style_conditional_delegate_call = true +# IDE1005: Delegate invocation can be simplified. +dotnet_diagnostic.IDE1005.severity = warning +# IDE1006: Naming Styles +dotnet_diagnostic.IDE1006.severity = error +# IDEOOO8: Use of var +dotnet_diagnostic.IDE0008.severity = none +# IDE0010: Add missing cases +dotnet_diagnostic.IDE0010.severity = none +# IDE0011: Add braces +csharp_prefer_braces = when_multiline +# IDE0025: Use expression body for properties +csharp_style_expression_bodied_properties = true +# IDE0026: Use expression body for indexers +csharp_style_expression_bodied_indexers = true +# IDE0027: Use expression body for accessors +csharp_style_expression_bodied_accessors = true +# IDE0046: Convert to conditional expression +dotnet_diagnostic.IDE0046.severity = none +# IDE0058: Expression value is never used +# csharp_style_unused_value_expression_statement_preference = discard_variable +dotnet_diagnostic.IDE0058.severity = none + +## Code Quality Rules +# CA1031: Do not catch general exception types +dotnet_diagnostic.CA1031.severity = none +# CA1822: Mark members as static +##dotnet_diagnostic.CA1822.severity = none +# CA1507: Use nameof to express symbol names +dotnet_diagnostic.CA1507.severity = error + +## Compiler +# CS0618: Type or member is obsolete +##dotnet_diagnostic.CS0618.severity = error +dotnet_diagnostic.CS0618.severity = warning +# CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1591.severity = none + +## StyleCop.Analyzers +# SA1000: Keywords should be spaced correctly +dotnet_diagnostic.SA1000.severity = error +# SA1005: Single line comments should begin with single space +dotnet_diagnostic.SA1005.severity = error +# SA1008 +# SA1025: Spacing?? +# SA1101: PrefixLocalCallsWithThis +dotnet_diagnostic.SA1101.severity = none +# SA1116: Split parameters should start on line after declaration +dotnet_diagnostic.SA1116.severity = none +# SA1118: Parameter should not span multiple lines +dotnet_diagnostic.SA1118.severity = warning +# SA1137: Elements should have the same indentation +dotnet_diagnostic.SA1137.severity = error +# SA1124: Do not use regions +dotnet_diagnostic.SA1124.severity = error +# SA1200: UsingDirectivesMustBePlacedWithinNamespace +dotnet_diagnostic.SA1200.severity = none +# SA1201: Elements should appear in the correct order +dotnet_diagnostic.SA1201.severity = error +# SA1202: Elements should be ordered by access +dotnet_diagnostic.SA1202.severity = error +# SA1203: Constants should appear before fields +dotnet_diagnostic.SA1203.severity = error +# SA1204: Static elements should appear before instance elements +dotnet_diagnostic.SA1204.severity = error +# SA1214: Readonly fields should appear before non-readonly fields +dotnet_diagnostic.SA1214.severity = error +# SA1306: Field names should begin with lower-case letter +dotnet_diagnostic.SA1306.severity = error +# SA1309: FieldNamesMustNotBeginWithUnderscore +dotnet_diagnostic.SA1309.severity = none +# SA1313: Parameter names should begin with lower-case letter +dotnet_diagnostic.SA1313.severity = error +# SA1414: Tuple types in signatures should have element names +dotnet_diagnostic.SA1414.severity = silent +# SA1503: Braces should not be omitted +dotnet_diagnostic.SA1503.severity = none +# SA1505: Opening braces should not be floowed by a blank line +dotnet_diagnostic.SA1505.severity= error +# SA1507: Code should not contain multiple blank lines in a row +dotnet_diagnostic.SA1507.severity = error +# SA1508: Closing brac should not be preceded by a blank line +dotnet_diagnostic.SA1508.severity= error +# SA1513: Closing brace should be followed by blank line +dotnet_diagnostic.SA1513.severity = error +# SA1514: Element documentation header should be preceded by blank line +dotnet_diagnostic.SA1514.severity = error +# SA1515: Single-line comment should be preceded by blank line +dotnet_diagnostic.SA1515.severity = warning +# SA1516: Elements should be separated by blank line +dotnet_diagnostic.SA1516.severity = error +# SA1600: Elements should be documented +dotnet_diagnostic.SA1600.severity = none +# SA1602: Enumeration items should not be documented +dotnet_diagnostic.SA1602.severity = none +# SA1623: Property summary documentation should match accessors +dotnet_diagnostic.SA1623.severity = warning +# SA1633: FileMustHaveHeader +dotnet_diagnostic.SA1633.severity = silent +# SA1636: File header copyright text should match +dotnet_diagnostic.SA1636.severity = none + +# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.SpacingRules' SA1028: Code should not contain trailing whitespace +dotnet_analyzer_diagnostic.category-StyleCop.CSharp.SpacingRules.severity = error + +dotnet_diagnostic.VSSpell001.severity = suggestion +dotnet_diagnostic.VSSpell002.severity = none + +# SA0001: XML comment analysis is disabled due to project configuration +dotnet_diagnostic.SA0001.severity = none + +# Ignore Generated XAML +[*.sg.cs] +# CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1591.severity = none +dotnet_analyzer_diagnostic.CS1591.severity = none +# generated_code = true + +[WindowsAppSDK-VersionInfo.cs] +dotnet_diagnostic.CS1591.severity = none diff --git a/templates/csharp/app-prism-dialog/.template.config/template.json b/templates/csharp/app-prism-dialog/.template.config/template.json index c7aa528..2d45872 100644 --- a/templates/csharp/app-prism-dialog/.template.config/template.json +++ b/templates/csharp/app-prism-dialog/.template.config/template.json @@ -17,7 +17,7 @@ "name": "Prism.Avalonia .NET - Sample Dialog App", "preferNameDirectory": true, "shortName": "prism.avalonia.app.dialog", - "sourceName": "PrismSimpleDialogTemplate", + "sourceName": "SampleApp", "defaultName": "PrismSimpleDialog", "tags": { "language": "C#", diff --git a/templates/csharp/app-prism-dialog/App.axaml b/templates/csharp/app-prism-dialog/App.axaml index dcfa1da..8a22348 100644 --- a/templates/csharp/app-prism-dialog/App.axaml +++ b/templates/csharp/app-prism-dialog/App.axaml @@ -1,10 +1,12 @@ - + x:Class="SampleApp.App" + xmlns:local="using:SampleApp" + RequestedThemeVariant="Default"> + + - - + + \ No newline at end of file diff --git a/templates/csharp/app-prism-dialog/App.axaml.cs b/templates/csharp/app-prism-dialog/App.axaml.cs index bb0686e..2ed75f8 100644 --- a/templates/csharp/app-prism-dialog/App.axaml.cs +++ b/templates/csharp/app-prism-dialog/App.axaml.cs @@ -1,43 +1,34 @@ -using System; -using Avalonia.Controls; +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Data.Core; +using Avalonia.Data.Core.Plugins; using Avalonia.Markup.Xaml; -using PrismSimpleDialogTemplate.ViewModels; -using PrismSimpleDialogTemplate.Views; using Prism.DryIoc; using Prism.Ioc; +using SampleApp.ViewModels; +using SampleApp.Views; -namespace PrismSimpleDialogTemplate; +namespace SampleApp; -public class App : PrismApplication +public partial class App : PrismApplication { - public App() - { - Console.WriteLine("Constructor"); - } - public override void Initialize() { - Console.WriteLine("Initialize"); AvaloniaXamlLoader.Load(this); - + + // Required when overriding Initialize base.Initialize(); } - protected override void OnInitialized() + protected override AvaloniaObject CreateShell() { - // Called after initialize + return Container.Resolve(); } - + protected override void RegisterTypes(IContainerRegistry containerRegistry) { - Console.WriteLine("Register Types"); - containerRegistry.Register(); - containerRegistry.RegisterDialog(); - } + // Register you Services, Views, Dialogs, etc. - protected override Window CreateShell() - { - Console.WriteLine("CreateShell()"); - return Container.Resolve(); + containerRegistry.RegisterDialog(); } -} \ No newline at end of file +} diff --git a/templates/csharp/app-prism-dialog/Assets/Prism.Avalonia.png b/templates/csharp/app-prism-dialog/Assets/Prism.Avalonia.png deleted file mode 100644 index 1d1c1149665fd89128c1edb857ddff7d3be97ea4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12857 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 - - WinExe - net8.0 - enable - true - app.manifest - true - latest - - - - - - - - - - - - - - - - - - - - diff --git a/templates/csharp/app-prism-dialog/Program.cs b/templates/csharp/app-prism-dialog/Program.cs index 3a1c0f1..5e783c8 100644 --- a/templates/csharp/app-prism-dialog/Program.cs +++ b/templates/csharp/app-prism-dialog/Program.cs @@ -1,21 +1,21 @@ -using Avalonia; +using System; +using Avalonia; -namespace PrismSimpleDialogTemplate; +namespace SampleApp; -public class Program +internal sealed class Program { - static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) => BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); - public static AppBuilder BuildAvaloniaApp() - { - var builder = AppBuilder - .Configure() - .UsePlatformDetect() - .With(new X11PlatformOptions { EnableMultiTouch = true, UseDBusMenu = true }) - .With(new Win32PlatformOptions { }) - .LogToTrace() - .UseSkia(); - - return builder; - } -} \ No newline at end of file + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() => AppBuilder + .Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); +} diff --git a/templates/csharp/app-prism-dialog/SampleApp.csproj b/templates/csharp/app-prism-dialog/SampleApp.csproj new file mode 100644 index 0000000..d4c9cb2 --- /dev/null +++ b/templates/csharp/app-prism-dialog/SampleApp.csproj @@ -0,0 +1,26 @@ + + + WinExe + net8.0 + enable + true + app.manifest + true + + + + + + + + + + + + + + + + + + diff --git a/templates/csharp/app-prism-dialog/ViewModels/MainWindowViewModel.cs b/templates/csharp/app-prism-dialog/ViewModels/MainWindowViewModel.cs index 8217169..dd0732d 100644 --- a/templates/csharp/app-prism-dialog/ViewModels/MainWindowViewModel.cs +++ b/templates/csharp/app-prism-dialog/ViewModels/MainWindowViewModel.cs @@ -1,67 +1,52 @@ -using Prism.Commands; -using Prism.Navigation.Regions; -using Prism.Services.Dialogs; +using DryIoc; +using Prism.Commands; +using Prism.Dialogs; -namespace PrismSimpleDialogTemplate.ViewModels; +namespace SampleApp.ViewModels; public class MainWindowViewModel : ViewModelBase { private readonly IDialogService _dialogService; - private string _returnedResult; + private string _returnedResult = string.Empty; - public MainWindowViewModel(IRegionManager regionManager, IDialogService dialogService) + public MainWindowViewModel(IDialogService dialogService) { _dialogService = dialogService; - Title = "Prism.Avalonia Dialog App"; + Title = "Prism.Avalonia - Dialog Sample App"; } - public DelegateCommand CmdShowDialog => new(() => - { - var message = "This is a message that should be shown in the dialog"; - - _dialogService.ShowDialog("NotificationDialogView", new DialogParameters($"message={message}"), r => - { - if (r is null) - { - Title = "Try Again"; - ReturnedResult = "Null Result Returned"; - } - - ReturnedResult = r.Result.ToString(); + public string ReturnedResult { get => _returnedResult; set => SetProperty(ref _returnedResult, value); } - Title = r.Result switch - { - ButtonResult.None => "Result is None", - ButtonResult.OK => "Result is OK", - ButtonResult.Cancel => "Result is Cancel", - _ => "Result was unknown" - }; - }); - }); - - public DelegateCommand CmdShowRegular => new DelegateCommand(() => + public DelegateCommand CmdShowMessageBox => new(() => { - _dialogService.Show("NotificationDialogView", r => - { - if (r is null) + // Simple modal dialog represented as a MessageBox + var title = "Modal MessageBox"; + var message = "Hello, I am a simple MessageBox modal window with an OK button.\n\n" + + "When too much text is added, a scrollbar will appear."; + + // Note: We're disregarding the dialog result + _dialogService.ShowDialog( + nameof(MessageBoxView), + new DialogParameters { - Title = "Try again"; - ReturnedResult = "Null result returned"; - } - - ReturnedResult = r.Result.ToString(); + { "title", title }, + { "message", message }, + }); + }); - // Same as if-statements, just a switch-expression. - Title = r.Result switch + public DelegateCommand CmdShowNonModalDialog => new(() => + { + // Simple modal dialog represented as a MessageBox + var title = "Non-Modal MessageBox"; + var message = "Hello, I am a non-modal MessageBox with an OK button.\n\n" + + "Notice how you can still interact with the parent window."; + + _dialogService.Show( + nameof(MessageBoxView), + new DialogParameters($"title={title}&message={message}"), r => { - ButtonResult.None => "Result is None", - ButtonResult.OK => "Result is OK", - ButtonResult.Cancel => "Result is Cancel", - _ => "Result was unknown", - }; - }); + ReturnedResult = r.Result.ToString(); + }); }); - - public string ReturnedResult { get => _returnedResult; set => SetProperty(ref _returnedResult, value); } } diff --git a/templates/csharp/app-prism-dialog/ViewModels/MessageBoxViewModel.cs b/templates/csharp/app-prism-dialog/ViewModels/MessageBoxViewModel.cs new file mode 100644 index 0000000..4b76af7 --- /dev/null +++ b/templates/csharp/app-prism-dialog/ViewModels/MessageBoxViewModel.cs @@ -0,0 +1,71 @@ +using Prism.Commands; +using Prism.Dialogs; +using Prism.Mvvm; + +namespace SampleApp.ViewModels; + +/// +/// Simple Message Box Dialog ViewModel that only supports an OK button. +/// +/// Parameter Inputs: +/// Title (string): Window's caption +/// Message (string): Text to display +/// +public class MessageBoxViewModel : BindableBase, IDialogAware +{ + private string _customMessage = string.Empty; + private string _title = "Notification"; + private int _maxHeight; + private int _maxWidth; + + public MessageBoxViewModel() + { + Title = "Alert!"; + + MaxHeight = 800; + MaxWidth = 600; + } + + public DialogCloseListener RequestClose { get; } + + public string Title { get => _title; set => SetProperty(ref _title, value); } + + public int MaxHeight { get => _maxHeight; set => SetProperty(ref _maxHeight, value); } + + public int MaxWidth { get => _maxWidth; set => SetProperty(ref _maxWidth, value); } + + public DelegateCommand CmdResult => new((string param) => + { + System.Diagnostics.Debug.WriteLine($"CmdResult('{param}')"); + + // None = 0, OK = 1, Cancel = 2, Abort = 3, Retry = 4, Ignore = 5, Yes = 6, No = 7 + ButtonResult result = ButtonResult.None; + + if (int.TryParse(param, out int intResult)) + result = (ButtonResult)intResult; + + RequestClose.Invoke(result); + }); + + public string CustomMessage { get => _customMessage; set => SetProperty(ref _customMessage, value); } + + /// Allow the dialog to close + public virtual bool CanCloseDialog() => true; + + public virtual void OnDialogClosed() + { + // Detach custom event handlers here, etc. + System.Diagnostics.Debug.WriteLine("OnDialogClosed()"); + } + + public void OnDialogOpened(IDialogParameters parameters) + { + System.Diagnostics.Debug.WriteLine("OnDialogOpened()"); + + var title = parameters.GetValue("title"); + if (!string.IsNullOrEmpty(title)) + Title = title; + + CustomMessage = parameters.GetValue("message"); + } +} diff --git a/templates/csharp/app-prism-dialog/ViewModels/NotificationDialogViewModel.cs b/templates/csharp/app-prism-dialog/ViewModels/NotificationDialogViewModel.cs deleted file mode 100644 index 479be90..0000000 --- a/templates/csharp/app-prism-dialog/ViewModels/NotificationDialogViewModel.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using Prism.Commands; -using Prism.Services.Dialogs; - -namespace PrismSimpleDialogTemplate.ViewModels; - -public class NotificationDialogViewModel : ViewModelBase, IDialogAware -{ - private readonly IDialogService _dialog; - private string _customMessage; - - public NotificationDialogViewModel() - { - Title = "Sample Dialog!"; - } - - public DelegateCommand CmdResult => new(s => - { - // None = 0 - // OK = 1 - // Cancel = 2 - // Abort = 3 - // Retry = 4 - // Ignore = 5 - // Yes = 6 - // No = 7 - ButtonResult result = ButtonResult.None; - - if (int.TryParse(s, out int intResult)) - result = (ButtonResult)intResult; - - RaiseRequestClose(new DialogResult(result)); - }); - - public event Action RequestClose; - - public virtual bool CanCloseDialog() - { - return true; - } - - public virtual void OnDialogClosed() - { - // Detatch custom eventhandlers here, etc. - } - - public void OnDialogOpened(IDialogParameters parameters) - { - CustomMessage = parameters.GetValue("message"); - } - - public string CustomMessage { get => _customMessage; set => SetProperty(ref _customMessage, value); } - - public virtual void RaiseRequestClose(IDialogResult dialogResult) - { - RequestClose?.Invoke(dialogResult); - } -} \ No newline at end of file diff --git a/templates/csharp/app-prism-dialog/ViewModels/ViewModelBase.cs b/templates/csharp/app-prism-dialog/ViewModels/ViewModelBase.cs index e632a12..229084d 100644 --- a/templates/csharp/app-prism-dialog/ViewModels/ViewModelBase.cs +++ b/templates/csharp/app-prism-dialog/ViewModels/ViewModelBase.cs @@ -1,45 +1,11 @@ -using Prism.Mvvm; -using Prism.Navigation.Regions; +using Prism.Mvvm; -namespace PrismSimpleDialogTemplate.ViewModels; +namespace SampleApp.ViewModels; -public class ViewModelBase : BindableBase, INavigationAware +public class ViewModelBase : BindableBase { - private string _title; + private string _title = string.Empty; - /// Gets or sets the title of the View. + /// Gets or sets the title of the view. public string Title { get => _title; set => SetProperty(ref _title, value); } - - /// - /// Called to determine if this instance can handle the navigation request. - /// Don't call this directly, use . - /// - /// The navigation context. - /// if this instance accepts the navigation request; otherwise, . - public virtual bool IsNavigationTarget(NavigationContext navigationContext) - { - // Auto-allow navigation - return OnNavigatingTo(navigationContext); - } - - /// Called when the implementer is being navigated away from. - /// The navigation context. - public virtual void OnNavigatedFrom(NavigationContext navigationContext) - { - } - - /// Called when the implementer has been navigated to. - /// The navigation context. - public virtual void OnNavigatedTo(NavigationContext navigationContext) - { - } - - /// Navigation validation checker. - /// Override for Prism 7.2's IsNavigationTarget. - /// The navigation context. - /// if this instance accepts the navigation request; otherwise, . - public virtual bool OnNavigatingTo(NavigationContext navigationContext) - { - return true; - } } diff --git a/templates/csharp/app-prism-dialog/Views/MainWindow.axaml b/templates/csharp/app-prism-dialog/Views/MainWindow.axaml index abf8841..b5c0982 100644 --- a/templates/csharp/app-prism-dialog/Views/MainWindow.axaml +++ b/templates/csharp/app-prism-dialog/Views/MainWindow.axaml @@ -2,22 +2,22 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:prism="http://prismlibrary.com/" - xmlns:vm="using:PrismSimpleDialogTemplate.ViewModels" - mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - x:Class="PrismSimpleDialogTemplate.Views.MainWindow" + xmlns:vm="using:SampleApp.ViewModels" + mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="350" + x:Class="SampleApp.Views.MainWindow" x:DataType="vm:MainWindowViewModel" - prism:ViewModelLocator.AutoWireViewModel="True" - Background="LightGray" + Icon="/Assets/logo.ico" + Height="350" Width="500" Title="{Binding Title}"> - +