From 3c0461facf2130a34cd25bd9e774189c89c3c0bf Mon Sep 17 00:00:00 2001 From: Mijail Todorovich Date: Sun, 24 Mar 2024 18:10:41 -0300 Subject: [PATCH 01/10] Fix regression in PR #1012 As @koal44 pointed out, https://github.com/lepoco/wpfui/pull/1012 introduced a bug which made the app crash when using FluentLeft navigation because updating the visual state tries to animate a width to or from OpenPaneLength=NaN. To avoid this, don't try to change the visual state for navigation view modes that don't have an open and a compact state. --- .../Controls/NavigationView/NavigationView.Base.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Base.cs b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Base.cs index 4ee6f9920..2e3be8132 100644 --- a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Base.cs +++ b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Base.cs @@ -68,6 +68,15 @@ public NavigationView() protected static void UpdateVisualState(NavigationView navigationView) { + // Skip display modes that don't have multiple states + if (navigationView.PaneDisplayMode is + NavigationViewPaneDisplayMode.LeftFluent or + NavigationViewPaneDisplayMode.Top or + NavigationViewPaneDisplayMode.Bottom) + { + return; + } + _ = VisualStateManager.GoToState( navigationView, navigationView.IsPaneOpen ? "PaneOpen" : "PaneCompact", @@ -94,7 +103,7 @@ protected override void OnInitialized(EventArgs e) private void OnLoaded(object sender, RoutedEventArgs e) { // TODO: Refresh - //UpdateVisualState((NavigationView)sender); + UpdateVisualState((NavigationView)sender); } /// From 5abcc0dd9198f97b605551e4df6a9c7ae01065d8 Mon Sep 17 00:00:00 2001 From: seasonyuu Date: Tue, 26 Mar 2024 14:24:34 +0800 Subject: [PATCH 02/10] TitleBarButton: Fix Foreground not using property value at initial --- src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs b/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs index daa0b1cbf..1b2d37020 100644 --- a/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs +++ b/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs @@ -115,6 +115,7 @@ private void TitleBarButton_Unloaded(object sender, RoutedEventArgs e) private void TitleBarButton_Loaded(object sender, RoutedEventArgs e) { + RenderButtonsForeground = ButtonsForeground; DependencyPropertyDescriptor .FromProperty(ButtonsForegroundProperty, typeof(Brush)) .AddValueChanged(this, OnButtonsForegroundChanged); From 1ac06092cc41d4a09f330989a01c51b8b052ff27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 23:44:15 +0000 Subject: [PATCH 03/10] Bump actions/configure-pages from 4 to 5 Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 4 to 5. - [Release notes](https://github.com/actions/configure-pages/releases) - [Commits](https://github.com/actions/configure-pages/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/configure-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/wpf-ui-cd-docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wpf-ui-cd-docs.yaml b/.github/workflows/wpf-ui-cd-docs.yaml index a1abfed1c..f6b39b482 100644 --- a/.github/workflows/wpf-ui-cd-docs.yaml +++ b/.github/workflows/wpf-ui-cd-docs.yaml @@ -28,7 +28,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Setup Pages - uses: actions/configure-pages@v4 + uses: actions/configure-pages@v5 - name: Use Node.js 18.x uses: actions/setup-node@v4 with: From 407de10fc84118f902590a66dadf067b09502b9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 23:41:41 +0000 Subject: [PATCH 04/10] Bump microsoft/setup-msbuild from 1.3 to 2 Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 1.3 to 2. - [Release notes](https://github.com/microsoft/setup-msbuild/releases) - [Changelog](https://github.com/microsoft/setup-msbuild/blob/main/building-release.md) - [Commits](https://github.com/microsoft/setup-msbuild/compare/v1.3...v2) --- updated-dependencies: - dependency-name: microsoft/setup-msbuild dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/wpf-ui-cd-extension.yaml | 2 +- .github/workflows/wpf-ui-cd-nuget.yaml | 2 +- .github/workflows/wpf-ui-pr-validator.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/wpf-ui-cd-extension.yaml b/.github/workflows/wpf-ui-cd-extension.yaml index ac179799e..8ae8bd31e 100644 --- a/.github/workflows/wpf-ui-cd-extension.yaml +++ b/.github/workflows/wpf-ui-cd-extension.yaml @@ -11,7 +11,7 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v4 - - uses: microsoft/setup-msbuild@v1.3 + - uses: microsoft/setup-msbuild@v2 with: msbuild-architecture: x64 - uses: nuget/setup-nuget@v2 diff --git a/.github/workflows/wpf-ui-cd-nuget.yaml b/.github/workflows/wpf-ui-cd-nuget.yaml index 20c957228..01d0a6d3b 100644 --- a/.github/workflows/wpf-ui-cd-nuget.yaml +++ b/.github/workflows/wpf-ui-cd-nuget.yaml @@ -11,7 +11,7 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v4 - - uses: microsoft/setup-msbuild@v1.3 + - uses: microsoft/setup-msbuild@v2 with: msbuild-architecture: x64 - uses: nuget/setup-nuget@v2 diff --git a/.github/workflows/wpf-ui-pr-validator.yaml b/.github/workflows/wpf-ui-pr-validator.yaml index c99cd6617..2d06c9322 100644 --- a/.github/workflows/wpf-ui-pr-validator.yaml +++ b/.github/workflows/wpf-ui-pr-validator.yaml @@ -13,7 +13,7 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v4 - - uses: microsoft/setup-msbuild@v1.3 + - uses: microsoft/setup-msbuild@v2 with: msbuild-architecture: x64 - uses: nuget/setup-nuget@v2 From c0ace5b18648a2f7ccc77eff388cae1fa6ef8555 Mon Sep 17 00:00:00 2001 From: koal44 <78566945+koal44@users.noreply.github.com> Date: Sun, 14 Apr 2024 01:12:13 -0700 Subject: [PATCH 05/10] Analyzer Warning Mitigation (#1039) * Fix null analyzer complaints: CS8602, CS8618, CS8603, CS8622, IDE0031 * Hide warnings related to IDE0008 related to using `var` keyword * Removed Coersion logic from IconSourceElementConverter, and placed in IconElement and IcounSourceElement classes instead * Cleaning single-line warnings: SA1005 - Removed commented-out Toolbox attributes - Replaced single-line commented-out code with multi-line * Fix missing braces or single-lined braces - Add stylecop supression of 1502 "element should not be on a single line" - Wrap with braces where needed * Fix warnings on registered dependency properties WPF0100, WPF0005, WPF0012 * Fix documentation warnings WPF0108, WPF0060, SA1642, SA1623 * Fix warnings about using language keywords - Use string, double, int rather than String, Double, Int32, etc - remove 'this' keyword when context is obvious * Fix warnings where attributes are on a single line SA1133 * When setting DPs, favor SetCurrentValue over the CLR setter. WPF0041 * Remove unnecessary things (parenthesis, assignments, etc). SA1119, IDE0059 * Fix order of operation warnings * Do not use regions SA1124. Clean VirtualizingPanelBase of warnings * Turn protected control fields into protected properties. fix some documentation warnings * Cleanup warnings in Interop classes and suppress warnings related to uper-casing and private fields * Continue cleaning up warnings in Wpf.Ui * Edit .editorconfig to suppress warnings related to valueconverters * Cleanup warning related to 'var' * Fix warnings * Split ContextMenu style from its loader dictionary There were some issue when having a class called ContextMenu that wasn't actually a contextmenu but a ResourceDictionary * Resolve "expression value is never used" IDE0058 warnings * Fix warnings related to collection initialization. There's still a lot of IDE0028 warnings as the auto fix really wants to use the C#12 collection expressions, which btw will trigger SA1010 warnings (https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687) * Remove unused suppressions * Supress IDE0290 (Use primary constructor). Just didn't seem necessary. * IDE0009 should be configured through dotnet_styles * Separate out the loader component from the Menu.xaml style. Justification: Menu was not a control.Menu, it's more like a hack to change private api settings. * Fix warnings on NavigationView.NavigationParent attached property * Fix warnings related to setting refernce types as default values. for dependency properties. Also fixed some enum warnings * Fix warnings * Fix regression error where the ContentDialog wouldn't appear and change name of ContentPresenter to DialogHost * Remove obsolete forceBacground parameters. Breaking changes * Remove redundant #if DEBUG directives around Debug.WriteLine calls * Fix some analyzer warnings --- .editorconfig | 30 +- src/Wpf.Ui.Demo.Console/Program.cs | 4 + .../Utilities/ThemeUtilities.cs | 12 +- .../Views/Pages/DataPage.xaml.cs | 4 +- .../Views/Pages/SettingsPage.xaml.cs | 2 +- .../Wpf.Ui.Demo.Console.csproj | 1 + src/Wpf.Ui.Demo.Mvvm/App.xaml.cs | 34 +- src/Wpf.Ui.Demo.Mvvm/AssemblyInfo.cs | 10 +- .../Helpers/EnumToBooleanConverter.cs | 12 +- src/Wpf.Ui.Demo.Mvvm/Models/AppConfig.cs | 6 +- .../Services/ApplicationHostService.cs | 6 +- src/Wpf.Ui.Demo.Mvvm/Services/PageService.cs | 8 +- .../ViewModels/DataViewModel.cs | 14 +- .../ViewModels/MainWindowViewModel.cs | 37 +- .../ViewModels/SettingsViewModel.cs | 12 +- src/Wpf.Ui.Demo.Mvvm/Views/MainWindow.xaml.cs | 4 - src/Wpf.Ui.Demo.Mvvm/Wpf.Ui.Demo.Mvvm.csproj | 1 + src/Wpf.Ui.Demo.Simple/AssemblyInfo.cs | 8 +- .../Views/Pages/DataPage.xaml.cs | 6 +- .../Views/Pages/SettingsPage.xaml.cs | 4 +- .../Wpf.Ui.Demo.Simple.csproj | 1 + src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj | 2 +- src/Wpf.Ui.FontMapper/FontSource.cs | 4 +- src/Wpf.Ui.FontMapper/Program.cs | 33 +- src/Wpf.Ui.Gallery/App.xaml.cs | 36 +- .../Controllers/MonacoController.cs | 11 +- .../Controls/ControlExample.xaml.cs | 42 +- .../GalleryNavigationPresenter.xaml.cs | 10 +- .../Controls/PageControlDocumentation.xaml.cs | 51 ++- .../Controls/TermsOfUseContentDialog.xaml.cs | 7 +- .../Controls/TypographyControl.xaml.cs | 15 +- .../ControlsLookup/ControlPages.cs | 8 +- .../ControlsLookup/GalleryPage.cs | 2 +- .../ControlsLookup/GalleryPageAttribute.cs | 3 +- src/Wpf.Ui.Gallery/GalleryAssembly.cs | 2 +- .../Helpers/NameToPageTypeConverter.cs | 2 +- .../PaneDisplayModeToIndexConverter.cs | 42 +- .../Models/Monaco/MonacoTheme.cs | 6 +- src/Wpf.Ui.Gallery/Models/NavigationCard.cs | 6 +- src/Wpf.Ui.Gallery/Models/Person.cs | 2 +- src/Wpf.Ui.Gallery/Models/Product.cs | 4 +- .../Services/WindowsProviderService.cs | 9 +- .../Pages/BasicInput/AnchorViewModel.cs | 2 + .../Pages/BasicInput/ButtonViewModel.cs | 4 + .../Pages/BasicInput/CheckBoxViewModel.cs | 17 +- .../Pages/BasicInput/ComboBoxViewModel.cs | 12 +- .../Pages/BasicInput/RadioButtonViewModel.cs | 2 + .../Pages/BasicInput/RatingViewModel.cs | 4 + .../Pages/BasicInput/ThumbRateViewModel.cs | 12 +- .../Pages/BasicInput/ToggleButtonViewModel.cs | 2 + .../Pages/BasicInput/ToggleSwitchViewModel.cs | 2 + .../Pages/Collections/DataGridViewModel.cs | 4 +- .../Pages/Collections/ListBoxViewModel.cs | 6 +- .../Pages/Collections/ListViewViewModel.cs | 6 +- .../ViewModels/Pages/DashboardViewModel.cs | 2 +- .../Pages/DesignGuidance/IconsViewModel.cs | 36 +- .../ContentDialogViewModel.cs | 15 +- .../DialogsAndFlyouts/FlyoutViewModel.cs | 2 + .../DialogsAndFlyouts/MessageBoxViewModel.cs | 10 +- .../DialogsAndFlyouts/SnackbarViewModel.cs | 2 +- .../Navigation/BreadcrumbBarViewModel.cs | 24 +- .../Pages/OpSystem/FilePickerViewModel.cs | 22 +- .../ViewModels/Pages/SettingsViewModel.cs | 6 +- .../Pages/StatusAndInfo/InfoBadgeViewModel.cs | 2 +- .../Pages/StatusAndInfo/InfoBarViewModel.cs | 8 +- .../Pages/Text/AutoSuggestBoxViewModel.cs | 2 +- .../Pages/Windows/WindowsViewModel.cs | 8 +- .../ViewModels/Windows/MainWindowViewModel.cs | 21 +- .../Windows/MonacoWindowViewModel.cs | 10 +- .../Windows/SandboxWindowViewModel.cs | 2 +- .../DialogsAndFlyouts/ContentDialog.xaml.cs | 1 - .../DialogsAndFlyoutsPage.xaml.cs | 1 - .../DialogsAndFlyouts/FlyoutPage.xaml.cs | 1 - .../DialogsAndFlyouts/MessageBoxPage.xaml.cs | 1 - .../DialogsAndFlyouts/SnackbarPage.xaml.cs | 1 - .../Views/Pages/Layout/CardActionPage.xaml.cs | 14 - .../Views/Pages/Layout/LayoutPage.xaml.cs | 1 - .../Views/Pages/Text/LabelPage.xaml.cs | 1 - .../Views/Pages/Text/NumberBoxPage.xaml.cs | 1 - .../Views/Pages/Text/PasswordBoxPage.xaml.cs | 1 - .../Views/Pages/Text/RichTextBoxPage.xaml.cs | 1 - .../Views/Pages/Text/TextBlockPage.xaml.cs | 1 - .../Views/Pages/Text/TextBoxPage.xaml.cs | 1 - .../Views/Windows/EditorWindow.xaml.cs | 390 +++++++++--------- .../Views/Windows/MainWindow.xaml.cs | 10 +- .../Views/Windows/SandboxWindow.xaml.cs | 13 +- src/Wpf.Ui.Gallery/Wpf.Ui.Gallery.csproj | 1 + .../Controls/CodeBlock.cs | 4 +- src/Wpf.Ui.SyntaxHighlight/Highlighter.cs | 45 +- .../Wpf.Ui.ToastNotifications.csproj | 1 + src/Wpf.Ui.Tray/Controls/NotifyIcon.cs | 156 +++---- src/Wpf.Ui.Tray/Hicon.cs | 26 +- src/Wpf.Ui.Tray/INotifyIcon.cs | 12 +- src/Wpf.Ui.Tray/INotifyIconService.cs | 10 +- .../Internal/InternalNotifyIconManager.cs | 17 +- src/Wpf.Ui.Tray/Interop/Shell32.cs | 23 +- src/Wpf.Ui.Tray/Interop/User32.cs | 63 ++- ...IconEvent.cs => NotifyIconEventHandler.cs} | 0 src/Wpf.Ui.Tray/NotifyIconService.cs | 44 +- src/Wpf.Ui.Tray/RoutedNotifyIconEvent.cs | 3 +- src/Wpf.Ui.Tray/TrayData.cs | 2 +- src/Wpf.Ui.Tray/TrayHandler.cs | 6 +- src/Wpf.Ui.Tray/TrayManager.cs | 21 +- src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj | 1 + .../Animations/TransitionAnimationProvider.cs | 28 +- .../ApplicationAccentColorManager.cs | 6 - .../Appearance/ApplicationThemeManager.cs | 33 +- src/Wpf.Ui/Appearance/ObservedWindow.cs | 4 - src/Wpf.Ui/Appearance/SystemThemeManager.cs | 8 +- src/Wpf.Ui/Appearance/SystemThemeWatcher.cs | 31 +- .../Appearance/WindowBackgroundManager.cs | 12 +- .../CardControlAutomationPeer.cs | 8 +- src/Wpf.Ui/ContentDialogService.cs | 39 +- src/Wpf.Ui/Controls/Anchor/Anchor.cs | 5 +- src/Wpf.Ui/Controls/Arc/Arc.cs | 10 +- .../Controls/AutoSuggestBox/AutoSuggestBox.cs | 130 ++---- .../AutoSuggestBoxTextChangedEventArgs.cs | 1 + src/Wpf.Ui/Controls/Badge/Badge.cs | 8 +- .../Controls/BreadcrumbBar/BreadcrumbBar.cs | 33 +- .../BreadcrumbBar/BreadcrumbBarItem.cs | 23 +- .../BreadcrumbBarItemClickedEventArgs.cs | 2 +- src/Wpf.Ui/Controls/Button/Button.cs | 78 ++-- .../CalendarDatePicker/CalendarDatePicker.cs | 16 +- src/Wpf.Ui/Controls/Card/Card.cs | 20 +- src/Wpf.Ui/Controls/CardAction/CardAction.cs | 27 +- src/Wpf.Ui/Controls/CardColor/CardColor.cs | 52 ++- .../Controls/CardControl/CardControl.cs | 26 +- .../Controls/CardExpander/CardExpander.cs | 31 +- .../ClientAreaBorder/ClientAreaBorder.cs | 54 ++- .../Controls/ContentDialog/ContentDialog.cs | 223 ++++------ .../ContentDialog/ContentDialogEventArgs.cs | 32 -- .../ContentDialogButtonClickEventArgs.cs | 15 + .../EventArgs/ContentDialogClosedEventArgs.cs | 15 + .../ContentDialogClosingEventArgs.cs | 17 + .../Controls/ContextMenu/ContextMenu.xaml | 4 +- .../Controls/ContextMenu/ContextMenu.xaml.cs | 53 --- .../ContextMenu/ContextMenuLoader.xaml | 11 + .../ContextMenu/ContextMenuLoader.xaml.cs | 60 +++ src/Wpf.Ui/Controls/ControlsServices.cs | 4 +- src/Wpf.Ui/Controls/DataGrid/DataGrid.cs | 34 +- src/Wpf.Ui/Controls/DateTimeHelper.cs | 73 ++-- .../Controls/DropDownButton/DropDownButton.cs | 20 +- .../DynamicScrollBar/DynamicScrollBar.cs | 48 ++- .../DynamicScrollViewer.cs | 34 +- src/Wpf.Ui/Controls/EventIdentifier.cs | 2 +- .../Controls/FluentWindow/FluentWindow.cs | 28 +- src/Wpf.Ui/Controls/Flyout/Flyout.cs | 16 +- .../HyperlinkButton/HyperlinkButton.cs | 8 +- .../{IThemeElement.cs => IThemeControl.cs} | 2 +- src/Wpf.Ui/Controls/IconElement/FontIcon.cs | 72 ++-- .../Controls/IconElement/IconElement.cs | 33 +- .../IconElement/IconElementConverter.cs | 6 +- .../Controls/IconElement/IconSourceElement.cs | 11 +- src/Wpf.Ui/Controls/IconElement/ImageIcon.cs | 12 +- src/Wpf.Ui/Controls/IconElement/SymbolIcon.cs | 20 +- .../Controls/IconSource/FontIconSource.cs | 22 +- src/Wpf.Ui/Controls/IconSource/IconSource.cs | 6 +- .../Controls/IconSource/SymbolIconSource.cs | 22 +- src/Wpf.Ui/Controls/Image/Image.cs | 25 +- src/Wpf.Ui/Controls/InfoBadge/InfoBadge.cs | 40 +- src/Wpf.Ui/Controls/InfoBar/InfoBar.cs | 38 +- src/Wpf.Ui/Controls/ItemRange.cs | 12 +- src/Wpf.Ui/Controls/Menu/Menu.xaml | 1 - src/Wpf.Ui/Controls/Menu/MenuItem.cs | 1 + src/Wpf.Ui/Controls/Menu/MenuLoader.xaml | 12 + .../Menu/{Menu.xaml.cs => MenuLoader.xaml.cs} | 16 +- src/Wpf.Ui/Controls/MessageBox/MessageBox.cs | 127 +++--- .../Controls/NavigationView/INavigableView.cs | 3 +- .../NavigationView/INavigationView.cs | 21 +- .../NavigationView/INavigationViewItem.cs | 20 +- .../NavigationView/NavigatedEventArgs.cs | 18 + ...ntArgs.cs => NavigatingCancelEventArgs.cs} | 11 +- .../NavigationView/NavigationCache.cs | 10 +- .../NavigationView/NavigationCacheMode.cs | 2 +- .../NavigationView.AttachedProperties.cs | 49 ++- .../NavigationView/NavigationView.Base.cs | 84 ++-- .../NavigationView/NavigationView.Events.cs | 37 +- .../NavigationView.Navigation.cs | 112 +++-- .../NavigationView/NavigationView.Parent.cs | 47 --- .../NavigationView.Properties.cs | 154 +++---- .../NavigationView.TemplateParts.cs | 35 +- .../NavigationView/NavigationViewActivator.cs | 70 ++-- .../NavigationViewBackButtonVisible.cs | 2 +- .../NavigationViewBreadcrumbItem.cs | 3 +- .../NavigationViewContentPresenter.cs | 28 +- .../NavigationView/NavigationViewItem.cs | 116 +++--- .../NavigationViewItemHeader.cs | 25 +- .../NavigationViewItemSeparator.cs | 4 +- .../NavigationViewPaneDisplayMode.cs | 4 +- .../Controls/NumberBox/INumberFormatter.cs | 8 +- .../Controls/NumberBox/INumberParser.cs | 8 +- src/Wpf.Ui/Controls/NumberBox/NumberBox.cs | 132 ++---- .../NumberBoxSpinButtonPlacementMode.cs | 2 +- .../NumberBox/NumberBoxValidationMode.cs | 2 +- .../NumberBox/ValidateNumberFormatter.cs | 20 +- .../Controls/PasswordBox/PasswordBox.cs | 93 +++-- .../Controls/ProgressRing/ProgressRing.cs | 50 +-- .../Controls/RatingControl/RatingControl.cs | 97 +++-- .../Controls/RichTextBox/RichTextBox.cs | 8 +- src/Wpf.Ui/Controls/ScrollDirection.cs | 3 +- src/Wpf.Ui/Controls/Snackbar/Snackbar.cs | 127 +++--- .../Controls/Snackbar/SnackbarPresenter.cs | 13 +- src/Wpf.Ui/Controls/SpacingMode.cs | 2 +- .../Controls/SplitButton/SplitButton.cs | 39 +- .../Controls/SplitButton/SplitButton.xaml | 2 +- src/Wpf.Ui/Controls/SymbolFilled.cs | 6 +- src/Wpf.Ui/Controls/SymbolGlyph.cs | 12 +- src/Wpf.Ui/Controls/SymbolRegular.cs | 6 +- src/Wpf.Ui/Controls/TextBlock/TextBlock.cs | 25 +- src/Wpf.Ui/Controls/TextBox/TextBox.cs | 82 ++-- src/Wpf.Ui/Controls/ThumbRate/ThumbRate.cs | 24 +- src/Wpf.Ui/Controls/TimePicker/TimePicker.cs | 20 +- src/Wpf.Ui/Controls/TitleBar/TitleBar.cs | 231 +++++------ .../Controls/TitleBar/TitleBarButton.cs | 71 ++-- .../Controls/ToggleSwitch/ToggleSwitch.cs | 28 +- src/Wpf.Ui/Controls/TreeGrid/TreeGrid.cs | 118 +++--- .../Controls/TreeGrid/TreeGridHeader.cs | 26 +- src/Wpf.Ui/Controls/TreeView/TreeViewItem.cs | 9 +- src/Wpf.Ui/Controls/TypedEventHandler.cs | 10 +- .../VirtualizingGridView.cs | 19 +- .../VirtualizingItemsControl.cs | 10 +- .../VirtualizingUniformGrid.cs | 3 +- .../VirtualizingPanelBase.cs | 145 +++---- .../VirtualizingWrapPanel.cs | 112 ++--- src/Wpf.Ui/Controls/Window/WindowBackdrop.cs | 81 ++-- ...ckButtonVisibilityToVisibilityConverter.cs | 18 +- .../Converters/FallbackBrushConverter.cs | 24 +- .../Converters/IconSourceElementConverter.cs | 37 +- .../LeftSplitCornerRadiusConverter.cs | 2 +- .../Converters/LeftSplitThicknessConverter.cs | 2 +- .../Converters/ProgressThicknessConverter.cs | 4 +- .../RightSplitCornerRadiusConverter.cs | 2 +- .../RightSplitThicknessConverter.cs | 2 +- .../Converters/TextToAsteriskConverter.cs | 2 +- src/Wpf.Ui/Extensions/ColorExtensions.cs | 70 ++-- .../Extensions/ContextMenuExtensions.cs | 18 +- src/Wpf.Ui/Extensions/FrameExtensions.cs | 2 +- src/Wpf.Ui/Extensions/UiElementExtensions.cs | 2 +- src/Wpf.Ui/Extensions/UriExtensions.cs | 10 +- src/Wpf.Ui/Hardware/DisplayDpi.cs | 8 +- src/Wpf.Ui/Hardware/DpiHelper.cs | 4 +- src/Wpf.Ui/Hardware/RenderingTier.cs | 2 +- src/Wpf.Ui/IContentDialogService.cs | 12 +- src/Wpf.Ui/INavigationService.cs | 6 +- src/Wpf.Ui/ISnackbarService.cs | 2 +- src/Wpf.Ui/Input/IRelayCommand.cs | 2 +- src/Wpf.Ui/Input/IRelayCommand{T}.cs | 2 +- src/Wpf.Ui/Input/RelayCommand{T}.cs | 10 +- src/Wpf.Ui/Interop/Dwmapi.cs | 16 +- src/Wpf.Ui/Interop/HRESULT.cs | 18 +- src/Wpf.Ui/Interop/Kernel32.cs | 11 +- src/Wpf.Ui/Interop/Libraries.cs | 54 ++- src/Wpf.Ui/Interop/ShObjIdl.cs | 32 +- src/Wpf.Ui/Interop/Shell32.cs | 29 +- src/Wpf.Ui/Interop/UnsafeNativeMethods.cs | 67 +-- src/Wpf.Ui/Interop/UnsafeReflection.cs | 4 +- src/Wpf.Ui/Interop/User32.cs | 67 +-- src/Wpf.Ui/Interop/UxTheme.cs | 12 +- src/Wpf.Ui/Interop/WinDef/POINT.cs | 8 +- src/Wpf.Ui/Interop/WinDef/POINTL.cs | 8 +- src/Wpf.Ui/Interop/WinDef/RECT.cs | 49 ++- src/Wpf.Ui/Interop/WinDef/RECTL.cs | 49 ++- src/Wpf.Ui/Interop/WinDef/SIZE.cs | 8 +- src/Wpf.Ui/Markup/Design.cs | 61 ++- src/Wpf.Ui/Markup/ThemeResource.cs | 1 - src/Wpf.Ui/NavigationService.cs | 4 +- src/Wpf.Ui/Properties/AssemblyInfo.cs | 1 - src/Wpf.Ui/Resources/Wpf.Ui.xaml | 3 +- .../SimpleContentDialogCreateOptions.cs | 8 +- src/Wpf.Ui/SnackbarService.cs | 9 +- src/Wpf.Ui/TaskBarService.cs | 8 +- src/Wpf.Ui/ThemeService.cs | 2 +- src/Wpf.Ui/UiApplication.cs | 39 +- src/Wpf.Ui/Win32/Utilities.cs | 51 ++- src/Wpf.Ui/Wpf.Ui.csproj | 1 + tests/Wpf.Ui.Gallery.UnitTests/UnitTest1.cs | 11 +- .../TransitionAnimationProviderTests.cs | 2 +- .../Extensions/SymbolExtensionsTests.cs | 4 +- 278 files changed, 3198 insertions(+), 3673 deletions(-) rename src/Wpf.Ui.Tray/{NotifyIconEvent.cs => NotifyIconEventHandler.cs} (100%) delete mode 100644 src/Wpf.Ui/Controls/ContentDialog/ContentDialogEventArgs.cs create mode 100644 src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogButtonClickEventArgs.cs create mode 100644 src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogClosedEventArgs.cs create mode 100644 src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogClosingEventArgs.cs delete mode 100644 src/Wpf.Ui/Controls/ContextMenu/ContextMenu.xaml.cs create mode 100644 src/Wpf.Ui/Controls/ContextMenu/ContextMenuLoader.xaml create mode 100644 src/Wpf.Ui/Controls/ContextMenu/ContextMenuLoader.xaml.cs rename src/Wpf.Ui/Controls/{IThemeElement.cs => IThemeControl.cs} (92%) create mode 100644 src/Wpf.Ui/Controls/Menu/MenuLoader.xaml rename src/Wpf.Ui/Controls/Menu/{Menu.xaml.cs => MenuLoader.xaml.cs} (63%) create mode 100644 src/Wpf.Ui/Controls/NavigationView/NavigatedEventArgs.cs rename src/Wpf.Ui/Controls/NavigationView/{NavigationViewEventArgs.cs => NavigatingCancelEventArgs.cs} (76%) delete mode 100644 src/Wpf.Ui/Controls/NavigationView/NavigationView.Parent.cs diff --git a/.editorconfig b/.editorconfig index 38c62724d..301fb13a8 100644 --- a/.editorconfig +++ b/.editorconfig @@ -50,10 +50,10 @@ file_header_template = This Source Code Form is subject to the terms of the MIT #### .NET Coding Conventions #### # this. and Me. preferences -dotnet_style_qualification_for_event = false:warning -dotnet_style_qualification_for_field = false:warning -dotnet_style_qualification_for_method = false:warning -dotnet_style_qualification_for_property = false:warning +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 @@ -95,8 +95,8 @@ dotnet_style_readonly_field = true:warning # var preferences csharp_style_var_elsewhere = false:warning -csharp_style_var_for_built_in_types = false:warning -csharp_style_var_when_type_is_apparent = 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 @@ -388,7 +388,7 @@ dotnet_diagnostic.SA1633.severity = none dotnet_diagnostic.SA1634.severity = none dotnet_diagnostic.SA1652.severity = none -dotnet_diagnostic.IDE0009.severity = none + # Additional Stylecop Analyzers dotnet_diagnostic.SA1111.severity = none @@ -397,3 +397,19 @@ dotnet_diagnostic.SA1204.severity = none dotnet_diagnostic.SA1208.severity = none 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.IDE0290.severity = none # Use primary constructor +dotnet_diagnostic.CS1591.severity = none # Missing XML comment for publicly visible type or member + # 15000+ warnings in the solution +dotnet_diagnostic.CA1510.severity = none # Use ArgumentNullException throw helper + # doesn't work with older versions of .NET + \ No newline at end of file diff --git a/src/Wpf.Ui.Demo.Console/Program.cs b/src/Wpf.Ui.Demo.Console/Program.cs index 515e5e98a..f49dc953f 100644 --- a/src/Wpf.Ui.Demo.Console/Program.cs +++ b/src/Wpf.Ui.Demo.Console/Program.cs @@ -3,11 +3,15 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. +using System.Diagnostics; + public static class Program { [STAThread] public static void Main(string[] args) { + Debug.WriteLine("Args: " + string.Join(", ", args)); + if (Application.Current is null) { Console.WriteLine($"Application.Current is null."); diff --git a/src/Wpf.Ui.Demo.Console/Utilities/ThemeUtilities.cs b/src/Wpf.Ui.Demo.Console/Utilities/ThemeUtilities.cs index fe37e05ce..6aead6217 100644 --- a/src/Wpf.Ui.Demo.Console/Utilities/ThemeUtilities.cs +++ b/src/Wpf.Ui.Demo.Console/Utilities/ThemeUtilities.cs @@ -12,25 +12,27 @@ public static void ApplyTheme(this FrameworkElement frameworkElement) { ApplicationThemeManager.Apply(frameworkElement); - ThemeChangedEvent themeChanged = (sender, args) => + void themeChanged(ApplicationTheme sender, Color args) { ApplicationThemeManager.Apply(frameworkElement); if (frameworkElement is Window window) { if (window != UiApplication.Current.MainWindow) + { WindowBackgroundManager.UpdateBackground( window, sender, - Wpf.Ui.Controls.WindowBackdropType.None, - true + Wpf.Ui.Controls.WindowBackdropType.None ); + } } - }; + } if (frameworkElement.IsLoaded) { ApplicationThemeManager.Changed += themeChanged; } + frameworkElement.Loaded += (s, e) => { ApplicationThemeManager.Changed += themeChanged; @@ -85,6 +87,7 @@ public static void ChangeTheme() ApplicationThemeManager.Apply(applicationTheme, updateAccent: false); } + /* /// /// Applies Resources in the . /// @@ -128,4 +131,5 @@ private static void Apply(FrameworkElement frameworkElement) frameworkElement.Resources[resource.Key] = resource.Value; } } + */ } diff --git a/src/Wpf.Ui.Demo.Console/Views/Pages/DataPage.xaml.cs b/src/Wpf.Ui.Demo.Console/Views/Pages/DataPage.xaml.cs index 023c4dc75..8991773e6 100644 --- a/src/Wpf.Ui.Demo.Console/Views/Pages/DataPage.xaml.cs +++ b/src/Wpf.Ui.Demo.Console/Views/Pages/DataPage.xaml.cs @@ -13,7 +13,7 @@ namespace Wpf.Ui.Demo.Console.Views.Pages; /// public partial class DataPage { - public ObservableCollection ColorsCollection = new(); + public ObservableCollection ColorsCollection = []; public DataPage() { @@ -30,6 +30,7 @@ private void InitializeData() var random = new Random(); for (int i = 0; i < 8192; i++) + { ColorsCollection.Add( new DataColor { @@ -43,5 +44,6 @@ private void InitializeData() ) } ); + } } } diff --git a/src/Wpf.Ui.Demo.Console/Views/Pages/SettingsPage.xaml.cs b/src/Wpf.Ui.Demo.Console/Views/Pages/SettingsPage.xaml.cs index e8e900114..f0dc451e2 100644 --- a/src/Wpf.Ui.Demo.Console/Views/Pages/SettingsPage.xaml.cs +++ b/src/Wpf.Ui.Demo.Console/Views/Pages/SettingsPage.xaml.cs @@ -43,6 +43,6 @@ private void OnDarkThemeRadioButtonChecked(object sender, RoutedEventArgs e) private string GetAssemblyVersion() { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() - ?? String.Empty; + ?? string.Empty; } } diff --git a/src/Wpf.Ui.Demo.Console/Wpf.Ui.Demo.Console.csproj b/src/Wpf.Ui.Demo.Console/Wpf.Ui.Demo.Console.csproj index fb5496e36..414d3fea4 100644 --- a/src/Wpf.Ui.Demo.Console/Wpf.Ui.Demo.Console.csproj +++ b/src/Wpf.Ui.Demo.Console/Wpf.Ui.Demo.Console.csproj @@ -8,6 +8,7 @@ true wpfui.ico $(NoWarn);SA1601 + True diff --git a/src/Wpf.Ui.Demo.Mvvm/App.xaml.cs b/src/Wpf.Ui.Demo.Mvvm/App.xaml.cs index bf821f1b3..d011783dc 100644 --- a/src/Wpf.Ui.Demo.Mvvm/App.xaml.cs +++ b/src/Wpf.Ui.Demo.Mvvm/App.xaml.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the MIT License. +// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. @@ -26,40 +26,42 @@ public partial class App private static readonly IHost _host = Host.CreateDefaultBuilder() .ConfigureAppConfiguration(c => { - c.SetBasePath(Path.GetDirectoryName(AppContext.BaseDirectory)); + var basePath = Path.GetDirectoryName(AppContext.BaseDirectory) + ?? throw new DirectoryNotFoundException("Unable to find the base directory of the application."); + _ = c.SetBasePath(basePath); }) .ConfigureServices( (context, services) => { // App Host - services.AddHostedService(); + _ = services.AddHostedService(); // Page resolver service - services.AddSingleton(); + _ = services.AddSingleton(); // Theme manipulation - services.AddSingleton(); + _ = services.AddSingleton(); // TaskBar manipulation - services.AddSingleton(); + _ = services.AddSingleton(); // Service containing navigation, same as INavigationWindow... but without window - services.AddSingleton(); + _ = services.AddSingleton(); // Main window with navigation - services.AddSingleton(); - services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); // Views and ViewModels - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); // Configuration - services.Configure(context.Configuration.GetSection(nameof(AppConfig))); + _ = services.Configure(context.Configuration.GetSection(nameof(AppConfig))); } ) .Build(); diff --git a/src/Wpf.Ui.Demo.Mvvm/AssemblyInfo.cs b/src/Wpf.Ui.Demo.Mvvm/AssemblyInfo.cs index 0d7e98bef..eaf149880 100644 --- a/src/Wpf.Ui.Demo.Mvvm/AssemblyInfo.cs +++ b/src/Wpf.Ui.Demo.Mvvm/AssemblyInfo.cs @@ -3,13 +3,7 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. -using System.Windows; - [assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located -//(used if a resource is not found in the page, -// app, or any theme specific resource dictionaries) + ResourceDictionaryLocation.None, // Where theme specific resource dictionaries are located (used if a resource is not found in the page, or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly // Where the generic resource dictionary is located (used if a resource is not found in the page, app, or any theme specific resource dictionaries) )] diff --git a/src/Wpf.Ui.Demo.Mvvm/Helpers/EnumToBooleanConverter.cs b/src/Wpf.Ui.Demo.Mvvm/Helpers/EnumToBooleanConverter.cs index 263b2be21..e2c8c8fc6 100644 --- a/src/Wpf.Ui.Demo.Mvvm/Helpers/EnumToBooleanConverter.cs +++ b/src/Wpf.Ui.Demo.Mvvm/Helpers/EnumToBooleanConverter.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the MIT License. +// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. @@ -12,11 +12,15 @@ internal class EnumToBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - if (parameter is not String enumString) + if (parameter is not string enumString) + { throw new ArgumentException("ExceptionEnumToBooleanConverterParameterMustBeAnEnumName"); + } if (!Enum.IsDefined(typeof(Wpf.Ui.Appearance.ApplicationTheme), value)) + { throw new ArgumentException("ExceptionEnumToBooleanConverterValueMustBeAnEnum"); + } var enumValue = Enum.Parse(typeof(Wpf.Ui.Appearance.ApplicationTheme), enumString); @@ -25,8 +29,10 @@ public object Convert(object value, Type targetType, object parameter, CultureIn public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - if (parameter is not String enumString) + if (parameter is not string enumString) + { throw new ArgumentException("ExceptionEnumToBooleanConverterParameterMustBeAnEnumName"); + } return Enum.Parse(typeof(Wpf.Ui.Appearance.ApplicationTheme), enumString); } diff --git a/src/Wpf.Ui.Demo.Mvvm/Models/AppConfig.cs b/src/Wpf.Ui.Demo.Mvvm/Models/AppConfig.cs index 7e437257d..0779b7a6c 100644 --- a/src/Wpf.Ui.Demo.Mvvm/Models/AppConfig.cs +++ b/src/Wpf.Ui.Demo.Mvvm/Models/AppConfig.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the MIT License. +// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. @@ -7,7 +7,7 @@ namespace Wpf.Ui.Demo.Mvvm.Models; public class AppConfig { - public string ConfigurationsFolder { get; set; } + public string? ConfigurationsFolder { get; set; } - public string AppPropertiesFileName { get; set; } + public string? AppPropertiesFileName { get; set; } } diff --git a/src/Wpf.Ui.Demo.Mvvm/Services/ApplicationHostService.cs b/src/Wpf.Ui.Demo.Mvvm/Services/ApplicationHostService.cs index c627bab09..f8187a529 100644 --- a/src/Wpf.Ui.Demo.Mvvm/Services/ApplicationHostService.cs +++ b/src/Wpf.Ui.Demo.Mvvm/Services/ApplicationHostService.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the MIT License. +// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. @@ -14,7 +14,7 @@ namespace Wpf.Ui.Demo.Mvvm.Services; public class ApplicationHostService : IHostedService { private readonly IServiceProvider _serviceProvider; - private INavigationWindow _navigationWindow; + private INavigationWindow? _navigationWindow; public ApplicationHostService(IServiceProvider serviceProvider) { @@ -53,7 +53,7 @@ private async Task HandleActivationAsync() )!; _navigationWindow!.ShowWindow(); - _navigationWindow.Navigate(typeof(Views.Pages.DashboardPage)); + _ = _navigationWindow.Navigate(typeof(Views.Pages.DashboardPage)); } await Task.CompletedTask; diff --git a/src/Wpf.Ui.Demo.Mvvm/Services/PageService.cs b/src/Wpf.Ui.Demo.Mvvm/Services/PageService.cs index 0b0ceb45b..1484a122e 100644 --- a/src/Wpf.Ui.Demo.Mvvm/Services/PageService.cs +++ b/src/Wpf.Ui.Demo.Mvvm/Services/PageService.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the MIT License. +// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. @@ -16,7 +16,7 @@ public class PageService : IPageService private readonly IServiceProvider _serviceProvider; /// - /// Creates new instance and attaches the . + /// Initializes a new instance of the class and attaches the . /// public PageService(IServiceProvider serviceProvider) { @@ -28,7 +28,9 @@ public PageService(IServiceProvider serviceProvider) where T : class { if (!typeof(FrameworkElement).IsAssignableFrom(typeof(T))) + { throw new InvalidOperationException("The page should be a WPF control."); + } return (T?)_serviceProvider.GetService(typeof(T)); } @@ -37,7 +39,9 @@ public PageService(IServiceProvider serviceProvider) public FrameworkElement? GetPage(Type pageType) { if (!typeof(FrameworkElement).IsAssignableFrom(pageType)) + { throw new InvalidOperationException("The page should be a WPF control."); + } return _serviceProvider.GetService(pageType) as FrameworkElement; } diff --git a/src/Wpf.Ui.Demo.Mvvm/ViewModels/DataViewModel.cs b/src/Wpf.Ui.Demo.Mvvm/ViewModels/DataViewModel.cs index c69801289..f97d43c7e 100644 --- a/src/Wpf.Ui.Demo.Mvvm/ViewModels/DataViewModel.cs +++ b/src/Wpf.Ui.Demo.Mvvm/ViewModels/DataViewModel.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the MIT License. +// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. @@ -14,12 +14,14 @@ public partial class DataViewModel : ObservableObject, INavigationAware private bool _isInitialized = false; [ObservableProperty] - private IEnumerable _colors; + private List _colors = []; public void OnNavigatedTo() { if (!_isInitialized) + { InitializeViewModel(); + } } public void OnNavigatedFrom() { } @@ -27,10 +29,11 @@ public void OnNavigatedFrom() { } private void InitializeViewModel() { var random = new Random(); - var colorCollection = new List(); + Colors.Clear(); for (int i = 0; i < 8192; i++) - colorCollection.Add( + { + Colors.Add( new DataColor { Color = new SolidColorBrush( @@ -43,8 +46,7 @@ private void InitializeViewModel() ) } ); - - Colors = colorCollection; + } _isInitialized = true; } diff --git a/src/Wpf.Ui.Demo.Mvvm/ViewModels/MainWindowViewModel.cs b/src/Wpf.Ui.Demo.Mvvm/ViewModels/MainWindowViewModel.cs index 08e56af05..d56ece2e6 100644 --- a/src/Wpf.Ui.Demo.Mvvm/ViewModels/MainWindowViewModel.cs +++ b/src/Wpf.Ui.Demo.Mvvm/ViewModels/MainWindowViewModel.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the MIT License. +// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. @@ -13,29 +13,32 @@ public partial class MainWindowViewModel : ObservableObject private bool _isInitialized = false; [ObservableProperty] - private string _applicationTitle = String.Empty; + private string _applicationTitle = string.Empty; [ObservableProperty] - private ObservableCollection _navigationItems = new(); + private ObservableCollection _navigationItems = []; [ObservableProperty] - private ObservableCollection _navigationFooter = new(); + private ObservableCollection _navigationFooter = []; [ObservableProperty] - private ObservableCollection _trayMenuItems = new(); + private ObservableCollection _trayMenuItems = []; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Demo")] public MainWindowViewModel(INavigationService navigationService) { if (!_isInitialized) + { InitializeViewModel(); + } } private void InitializeViewModel() { ApplicationTitle = "WPF UI - MVVM Demo"; - NavigationItems = new ObservableCollection - { + NavigationItems = + [ new NavigationViewItem() { Content = "Home", @@ -47,23 +50,23 @@ private void InitializeViewModel() Content = "Data", Icon = new SymbolIcon { Symbol = SymbolRegular.DataHistogram24 }, TargetPageType = typeof(Views.Pages.DataPage) - } - }; + }, + ]; - NavigationFooter = new ObservableCollection - { + NavigationFooter = + [ new NavigationViewItem() { Content = "Settings", Icon = new SymbolIcon { Symbol = SymbolRegular.Settings24 }, TargetPageType = typeof(Views.Pages.SettingsPage) - } - }; + }, + ]; - TrayMenuItems = new ObservableCollection - { - new MenuItem { Header = "Home", Tag = "tray_home" } - }; + TrayMenuItems = + [ + new() { Header = "Home", Tag = "tray_home" } + ]; _isInitialized = true; } diff --git a/src/Wpf.Ui.Demo.Mvvm/ViewModels/SettingsViewModel.cs b/src/Wpf.Ui.Demo.Mvvm/ViewModels/SettingsViewModel.cs index 86c56258f..3d6f6f613 100644 --- a/src/Wpf.Ui.Demo.Mvvm/ViewModels/SettingsViewModel.cs +++ b/src/Wpf.Ui.Demo.Mvvm/ViewModels/SettingsViewModel.cs @@ -12,7 +12,7 @@ public partial class SettingsViewModel : ObservableObject, INavigationAware private bool _isInitialized = false; [ObservableProperty] - private string _appVersion = String.Empty; + private string _appVersion = string.Empty; [ObservableProperty] private Wpf.Ui.Appearance.ApplicationTheme _currentApplicationTheme = Wpf.Ui @@ -23,7 +23,9 @@ public partial class SettingsViewModel : ObservableObject, INavigationAware public void OnNavigatedTo() { if (!_isInitialized) + { InitializeViewModel(); + } } public void OnNavigatedFrom() { } @@ -36,10 +38,10 @@ private void InitializeViewModel() _isInitialized = true; } - private string GetAssemblyVersion() + private static string GetAssemblyVersion() { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() - ?? String.Empty; + ?? string.Empty; } [RelayCommand] @@ -49,7 +51,9 @@ private void OnChangeTheme(string parameter) { case "theme_light": if (CurrentApplicationTheme == Wpf.Ui.Appearance.ApplicationTheme.Light) + { break; + } Wpf.Ui.Appearance.ApplicationThemeManager.Apply(Wpf.Ui.Appearance.ApplicationTheme.Light); CurrentApplicationTheme = Wpf.Ui.Appearance.ApplicationTheme.Light; @@ -58,7 +62,9 @@ private void OnChangeTheme(string parameter) default: if (CurrentApplicationTheme == Wpf.Ui.Appearance.ApplicationTheme.Dark) + { break; + } Wpf.Ui.Appearance.ApplicationThemeManager.Apply(Wpf.Ui.Appearance.ApplicationTheme.Dark); CurrentApplicationTheme = Wpf.Ui.Appearance.ApplicationTheme.Dark; diff --git a/src/Wpf.Ui.Demo.Mvvm/Views/MainWindow.xaml.cs b/src/Wpf.Ui.Demo.Mvvm/Views/MainWindow.xaml.cs index a6dd4a9a0..b2280e8e4 100644 --- a/src/Wpf.Ui.Demo.Mvvm/Views/MainWindow.xaml.cs +++ b/src/Wpf.Ui.Demo.Mvvm/Views/MainWindow.xaml.cs @@ -31,8 +31,6 @@ INavigationService navigationService navigationService.SetNavigationControl(RootNavigation); } - #region INavigationWindow methods - public INavigationView GetNavigation() => RootNavigation; public bool Navigate(Type pageType) => RootNavigation.Navigate(pageType); @@ -43,8 +41,6 @@ INavigationService navigationService public void CloseWindow() => Close(); - #endregion INavigationWindow methods - /// /// Raises the closed event. /// diff --git a/src/Wpf.Ui.Demo.Mvvm/Wpf.Ui.Demo.Mvvm.csproj b/src/Wpf.Ui.Demo.Mvvm/Wpf.Ui.Demo.Mvvm.csproj index 1f3462e02..df10b154a 100644 --- a/src/Wpf.Ui.Demo.Mvvm/Wpf.Ui.Demo.Mvvm.csproj +++ b/src/Wpf.Ui.Demo.Mvvm/Wpf.Ui.Demo.Mvvm.csproj @@ -11,6 +11,7 @@ applicationIcon.ico AnyCPU;x64 $(NoWarn);SA1601 + True diff --git a/src/Wpf.Ui.Demo.Simple/AssemblyInfo.cs b/src/Wpf.Ui.Demo.Simple/AssemblyInfo.cs index 77c6c5db5..273de9fbc 100644 --- a/src/Wpf.Ui.Demo.Simple/AssemblyInfo.cs +++ b/src/Wpf.Ui.Demo.Simple/AssemblyInfo.cs @@ -1,10 +1,6 @@ using System.Windows; [assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located -//(used if a resource is not found in the page, -// app, or any theme specific resource dictionaries) + ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located (used if a resource is not found in the page, or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly // where the generic resource dictionary is located (used if a resource is not found in the page, app, or any theme specific resource dictionaries) )] diff --git a/src/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml.cs b/src/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml.cs index 577720b35..99dc09c0b 100644 --- a/src/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml.cs +++ b/src/Wpf.Ui.Demo.Simple/Views/Pages/DataPage.xaml.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the MIT License. +// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. @@ -15,7 +15,7 @@ namespace Wpf.Ui.Demo.Simple.Views.Pages; /// public partial class DataPage { - public ObservableCollection ColorsCollection = new(); + public ObservableCollection ColorsCollection { get; private set; } = []; public DataPage() { @@ -30,6 +30,7 @@ private void InitializeData() var random = new Random(); for (int i = 0; i < 8192; i++) + { ColorsCollection.Add( new DataColor { @@ -43,5 +44,6 @@ private void InitializeData() ) } ); + } } } diff --git a/src/Wpf.Ui.Demo.Simple/Views/Pages/SettingsPage.xaml.cs b/src/Wpf.Ui.Demo.Simple/Views/Pages/SettingsPage.xaml.cs index e48c18e52..f040ce5ca 100644 --- a/src/Wpf.Ui.Demo.Simple/Views/Pages/SettingsPage.xaml.cs +++ b/src/Wpf.Ui.Demo.Simple/Views/Pages/SettingsPage.xaml.cs @@ -40,9 +40,9 @@ private void OnDarkThemeRadioButtonChecked(object sender, RoutedEventArgs e) Appearance.ApplicationThemeManager.Apply(ApplicationTheme.Dark); } - private string GetAssemblyVersion() + private static string GetAssemblyVersion() { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() - ?? String.Empty; + ?? string.Empty; } } diff --git a/src/Wpf.Ui.Demo.Simple/Wpf.Ui.Demo.Simple.csproj b/src/Wpf.Ui.Demo.Simple/Wpf.Ui.Demo.Simple.csproj index 1d6697725..9d80251c7 100644 --- a/src/Wpf.Ui.Demo.Simple/Wpf.Ui.Demo.Simple.csproj +++ b/src/Wpf.Ui.Demo.Simple/Wpf.Ui.Demo.Simple.csproj @@ -10,6 +10,7 @@ applicationIcon.ico AnyCPU;x64 $(NoWarn);SA1601 + True diff --git a/src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj b/src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj index 16be6fe74..32b894779 100644 --- a/src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj +++ b/src/Wpf.Ui.Extension/Wpf.Ui.Extension.csproj @@ -114,4 +114,4 @@ - + \ No newline at end of file diff --git a/src/Wpf.Ui.FontMapper/FontSource.cs b/src/Wpf.Ui.FontMapper/FontSource.cs index d3e768da2..07f91a684 100644 --- a/src/Wpf.Ui.FontMapper/FontSource.cs +++ b/src/Wpf.Ui.FontMapper/FontSource.cs @@ -1,4 +1,4 @@ -namespace Wpf.Ui.FontMapper; +namespace Wpf.Ui.FontMapper; class FontSource { @@ -6,7 +6,7 @@ class FontSource public string Description { get; private set; } public string SourcePath { get; } public string DestinationPath { get; } - public IDictionary Contents { get; private set; } + public IDictionary Contents { get; set; } = new Dictionary(); public FontSource(string name, string description, string sourcePath, string destinationPath) { diff --git a/src/Wpf.Ui.FontMapper/Program.cs b/src/Wpf.Ui.FontMapper/Program.cs index 6ffd72f41..62709b18e 100644 --- a/src/Wpf.Ui.FontMapper/Program.cs +++ b/src/Wpf.Ui.FontMapper/Program.cs @@ -10,12 +10,8 @@ Console.WriteLine("Fluent System Icons Mapper"); System.Diagnostics.Debug.WriteLine("INFO | Fluent System Icons Mapper", "Wpf.Ui.FontMapper"); -var workingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); - -if (workingDirectory is null) -{ - throw new ArgumentNullException(nameof(workingDirectory)); -} +var workingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + ?? throw new InvalidOperationException("Could not determine the working directory."); var regularIcons = new FontSource( "SymbolRegular", @@ -41,23 +37,23 @@ await httpClient.GetFromJsonAsync>( ) ) ?.Last() - ?.Ref.Replace("refs/tags/", String.Empty) + ?.Ref.Replace("refs/tags/", string.Empty) .Trim() ?? throw new Exception("Unable to parse the version string"); } string FormatIconName(string rawIconName) { rawIconName = rawIconName - .Replace("ic_fluent_", String.Empty) - .Replace("_regular", String.Empty) - .Replace("_filled", String.Empty); + .Replace("ic_fluent_", string.Empty) + .Replace("_regular", string.Empty) + .Replace("_filled", string.Empty); - var iconName = String.Empty; + var iconName = string.Empty; foreach (var newPart in rawIconName.Split('_')) { var charactersArray = newPart.ToCharArray(); - charactersArray[0] = Char.ToUpper(charactersArray[0]); + charactersArray[0] = char.ToUpper(charactersArray[0]); iconName += new string(charactersArray); } @@ -114,9 +110,9 @@ async Task WriteToFile(FontSource singleFont, string fileRootDirectory) ) .AppendLine("// Copyright (C) Leszek Pomianowski and WPF UI Contributors.") .AppendLine("// All Rights Reserved.") - .AppendLine(String.Empty) + .AppendLine() .AppendLine("namespace Wpf.Ui.Controls;") - .AppendLine(String.Empty) + .AppendLine() .AppendLine("/// ") .AppendLine($"/// {singleFont.Description.Replace("\n", "\n/// ")}") .AppendLine("/// ") @@ -127,9 +123,9 @@ async Task WriteToFile(FontSource singleFont, string fileRootDirectory) .AppendLine(" /// Actually, this icon is not empty, but makes it easier to navigate.") .AppendLine(" /// ") .AppendLine(" Empty = 0x0,") - .AppendLine(String.Empty) + .AppendLine() .AppendLine(" // Automatically generated, may contain bugs.") - .AppendLine(String.Empty); + .AppendLine(); foreach (KeyValuePair singleIcon in singleFont.Contents) { @@ -137,7 +133,7 @@ async Task WriteToFile(FontSource singleFont, string fileRootDirectory) if (singleIcon.Value < 32) { _ = enumMapStringBuilder - .AppendLine(String.Empty) + .AppendLine() .AppendLine(" /// ") .AppendLine(" /// Blank icon.") .AppendLine(" /// "); @@ -148,7 +144,7 @@ async Task WriteToFile(FontSource singleFont, string fileRootDirectory) _ = enumMapStringBuilder .AppendLine("}") - .AppendLine(String.Empty) + .AppendLine() .AppendLine("#pragma warning restore CS1591") .Append("\r\n"); @@ -160,6 +156,7 @@ async Task WriteToFile(FontSource singleFont, string fileRootDirectory) } await File.WriteAllTextAsync(destinationPath, enumMapStringBuilder.ToString()); + Console.WriteLine($"Wrote to file \"{destinationPath}\""); } await WriteToFile(regularIcons, workingDirectory); diff --git a/src/Wpf.Ui.Gallery/App.xaml.cs b/src/Wpf.Ui.Gallery/App.xaml.cs index 5a9d7528b..56863b871 100644 --- a/src/Wpf.Ui.Gallery/App.xaml.cs +++ b/src/Wpf.Ui.Gallery/App.xaml.cs @@ -13,7 +13,6 @@ namespace Wpf.Ui.Gallery; -#pragma warning disable IDE0058 // Expression value is never used public partial class App { // The .NET Generic Host provides dependency injection, configuration, logging, and other services. @@ -24,33 +23,33 @@ public partial class App private static readonly IHost _host = Host.CreateDefaultBuilder() .ConfigureAppConfiguration(c => { - c.SetBasePath(AppContext.BaseDirectory); + _ = c.SetBasePath(AppContext.BaseDirectory); }) .ConfigureServices( - (_, services) => + (_1, services) => { // App Host - services.AddHostedService(); + _ = services.AddHostedService(); // Main window container with navigation - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); // Top-level pages - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); + _ = services.AddSingleton(); // All other pages and view models - services.AddTransientFromNamespace("Wpf.Ui.Gallery.Views", GalleryAssembly.Asssembly); - services.AddTransientFromNamespace("Wpf.Ui.Gallery.ViewModels", GalleryAssembly.Asssembly); + _ = services.AddTransientFromNamespace("Wpf.Ui.Gallery.Views", GalleryAssembly.Asssembly); + _ = services.AddTransientFromNamespace("Wpf.Ui.Gallery.ViewModels", GalleryAssembly.Asssembly); } ) .Build(); @@ -92,4 +91,3 @@ private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledEx // For more info see https://docs.microsoft.com/en-us/dotnet/api/system.windows.application.dispatcherunhandledexception?view=windowsdesktop-6.0 } } -#pragma warning restore IDE0058 // Expression value is never used diff --git a/src/Wpf.Ui.Gallery/Controllers/MonacoController.cs b/src/Wpf.Ui.Gallery/Controllers/MonacoController.cs index 5ea1c948b..9530789b0 100644 --- a/src/Wpf.Ui.Gallery/Controllers/MonacoController.cs +++ b/src/Wpf.Ui.Gallery/Controllers/MonacoController.cs @@ -16,7 +16,7 @@ public class MonacoController private const string EditorObject = "wpfUiMonacoEditor"; - private volatile WebView2 _webView; + private readonly WebView2 _webView; public MonacoController(WebView2 webView) { @@ -25,7 +25,7 @@ public MonacoController(WebView2 webView) public async Task CreateAsync() { - await _webView.ExecuteScriptAsync( + _ = await _webView.ExecuteScriptAsync( $$""" const {{EditorObject}} = monaco.editor.create(document.querySelector('{{EditorContainerSelector}}')); window.onresize = () => {{{EditorObject}}.layout();} @@ -35,12 +35,11 @@ await _webView.ExecuteScriptAsync( public async Task SetThemeAsync(ApplicationTheme appApplicationTheme) { + // TODO: Parse theme from object const string uiThemeName = "wpf-ui-app-theme"; var baseMonacoTheme = appApplicationTheme == ApplicationTheme.Light ? "vs" : "vs-dark"; - // TODO: Parse theme from object - - await _webView.ExecuteScriptAsync( + _ = await _webView.ExecuteScriptAsync( $$$""" monaco.editor.defineTheme('{{{uiThemeName}}}', { base: '{{{baseMonacoTheme}}}', @@ -72,7 +71,9 @@ public async Task SetContentAsync(string contents) public void DispatchScript(string script) { if (_webView == null) + { return; + } Application.Current.Dispatcher.InvokeAsync(async () => await _webView!.ExecuteScriptAsync(script)); } diff --git a/src/Wpf.Ui.Gallery/Controls/ControlExample.xaml.cs b/src/Wpf.Ui.Gallery/Controls/ControlExample.xaml.cs index 0f0905cb8..218613d1e 100644 --- a/src/Wpf.Ui.Gallery/Controls/ControlExample.xaml.cs +++ b/src/Wpf.Ui.Gallery/Controls/ControlExample.xaml.cs @@ -10,6 +10,7 @@ namespace Wpf.Ui.Gallery.Controls; [ContentProperty(nameof(ExampleContent))] public class ControlExample : Control { + /// Identifies the dependency property. public static readonly DependencyProperty HeaderTextProperty = DependencyProperty.Register( nameof(HeaderText), typeof(string), @@ -17,6 +18,7 @@ public class ControlExample : Control new PropertyMetadata(null) ); + /// Identifies the dependency property. public static readonly DependencyProperty ExampleContentProperty = DependencyProperty.Register( nameof(ExampleContent), typeof(object), @@ -24,6 +26,7 @@ public class ControlExample : Control new PropertyMetadata(null) ); + /// Identifies the dependency property. public static readonly DependencyProperty XamlCodeProperty = DependencyProperty.Register( nameof(XamlCode), typeof(string), @@ -31,16 +34,20 @@ public class ControlExample : Control new PropertyMetadata(null) ); + /// Identifies the dependency property. public static readonly DependencyProperty XamlCodeSourceProperty = DependencyProperty.Register( nameof(XamlCodeSource), typeof(Uri), typeof(ControlExample), new PropertyMetadata( null, - static (o, args) => ((ControlExample)o).OnXamlCodeSourceChanged((Uri)args.NewValue) - ) + static (o, args) => + { + ((ControlExample)o).OnXamlCodeSourceChanged((Uri?)args.NewValue); + }) ); + /// Identifies the dependency property. public static readonly DependencyProperty CsharpCodeProperty = DependencyProperty.Register( nameof(CsharpCode), typeof(string), @@ -48,19 +55,22 @@ public class ControlExample : Control new PropertyMetadata(null) ); + /// Identifies the dependency property. public static readonly DependencyProperty CsharpCodeSourceProperty = DependencyProperty.Register( nameof(CsharpCodeSource), typeof(Uri), typeof(ControlExample), new PropertyMetadata( null, - static (o, args) => ((ControlExample)o).OnCsharpCodeSourceChanged((Uri)args.NewValue) - ) + static (o, args) => + { + ((ControlExample)o).OnCsharpCodeSourceChanged((Uri?)args.NewValue); + }) ); public string? HeaderText { - get => (string)GetValue(HeaderTextProperty); + get => (string?)GetValue(HeaderTextProperty); set => SetValue(HeaderTextProperty, value); } @@ -72,45 +82,45 @@ public object? ExampleContent public string? XamlCode { - get => (string)GetValue(XamlCodeProperty); + get => (string?)GetValue(XamlCodeProperty); set => SetValue(XamlCodeProperty, value); } public Uri? XamlCodeSource { - get => (Uri)GetValue(XamlCodeSourceProperty); + get => (Uri?)GetValue(XamlCodeSourceProperty); set => SetValue(XamlCodeSourceProperty, value); } public string? CsharpCode { - get => (string)GetValue(CsharpCodeProperty); + get => (string?)GetValue(CsharpCodeProperty); set => SetValue(CsharpCodeProperty, value); } public Uri? CsharpCodeSource { - get => (Uri)GetValue(CsharpCodeSourceProperty); + get => (Uri?)GetValue(CsharpCodeSourceProperty); set => SetValue(CsharpCodeSourceProperty, value); } - private void OnXamlCodeSourceChanged(Uri uri) + private void OnXamlCodeSourceChanged(Uri? uri) { - XamlCode = LoadResource(uri); + SetCurrentValue(XamlCodeProperty, LoadResource(uri)); } - private void OnCsharpCodeSourceChanged(Uri uri) + private void OnCsharpCodeSourceChanged(Uri? uri) { - CsharpCode = LoadResource(uri); + SetCurrentValue(CsharpCodeProperty, LoadResource(uri)); } - private static string LoadResource(Uri uri) + private static string LoadResource(Uri? uri) { try { - if (Application.GetResourceStream(uri) is not { } steamInfo) + if (uri is null || Application.GetResourceStream(uri) is not { } steamInfo) { - return String.Empty; + return string.Empty; } using StreamReader streamReader = new(steamInfo.Stream, Encoding.UTF8); diff --git a/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml.cs b/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml.cs index 28c1b652a..f198369fd 100644 --- a/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml.cs +++ b/src/Wpf.Ui.Gallery/Controls/GalleryNavigationPresenter.xaml.cs @@ -7,9 +7,7 @@ namespace Wpf.Ui.Gallery.Controls; public class GalleryNavigationPresenter : System.Windows.Controls.Control { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( nameof(ItemsSource), typeof(object), @@ -17,9 +15,7 @@ public class GalleryNavigationPresenter : System.Windows.Controls.Control new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty TemplateButtonCommandProperty = DependencyProperty.Register( nameof(TemplateButtonCommand), typeof(Wpf.Ui.Input.IRelayCommand), @@ -57,11 +53,9 @@ private void OnTemplateButtonClick(Type? pageType) navigationService.Navigate(pageType); } -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {nameof(GalleryNavigationPresenter)} navigated, ({pageType})", "Wpf.Ui.Gallery" ); -#endif } } diff --git a/src/Wpf.Ui.Gallery/Controls/PageControlDocumentation.xaml.cs b/src/Wpf.Ui.Gallery/Controls/PageControlDocumentation.xaml.cs index 2c6416377..31a09a92b 100644 --- a/src/Wpf.Ui.Gallery/Controls/PageControlDocumentation.xaml.cs +++ b/src/Wpf.Ui.Gallery/Controls/PageControlDocumentation.xaml.cs @@ -13,27 +13,42 @@ public class PageControlDocumentation : Control public static readonly DependencyProperty ShowProperty = DependencyProperty.RegisterAttached( "Show", typeof(bool), - typeof(FrameworkElement), + typeof(PageControlDocumentation), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender) ); public static readonly DependencyProperty DocumentationTypeProperty = DependencyProperty.RegisterAttached( "DocumentationType", typeof(Type), - typeof(FrameworkElement), + typeof(PageControlDocumentation), new FrameworkPropertyMetadata(null) ); + /// Helper for getting from . + /// to read from. + /// Show property value. + [AttachedPropertyBrowsableForType(typeof(FrameworkElement))] public static bool GetShow(FrameworkElement target) => (bool)target.GetValue(ShowProperty); + /// Helper for setting on . + /// to set on. + /// Show property value. public static void SetShow(FrameworkElement target, bool show) => target.SetValue(ShowProperty, show); + /// Helper for getting from . + /// to read from. + /// DocumentationType property value. + [AttachedPropertyBrowsableForType(typeof(FrameworkElement))] public static Type? GetDocumentationType(FrameworkElement target) => (Type?)target.GetValue(DocumentationTypeProperty); - public static void SetDocumentationType(FrameworkElement target, Type type) => + /// Helper for setting on . + /// to set on. + /// DocumentationType property value. + public static void SetDocumentationType(FrameworkElement target, Type? type) => target.SetValue(DocumentationTypeProperty, type); + /// Identifies the dependency property. public static readonly DependencyProperty NavigationViewProperty = DependencyProperty.Register( nameof(NavigationView), typeof(INavigationView), @@ -41,6 +56,7 @@ public static void SetDocumentationType(FrameworkElement target, Type type) => new FrameworkPropertyMetadata(null) ); + /// Identifies the dependency property. public static readonly DependencyProperty IsDocumentationLinkVisibleProperty = DependencyProperty.Register( nameof(IsDocumentationLinkVisible), @@ -49,6 +65,7 @@ public static void SetDocumentationType(FrameworkElement target, Type type) => new FrameworkPropertyMetadata(Visibility.Collapsed) ); + /// Identifies the dependency property. public static readonly DependencyProperty TemplateButtonCommandProperty = DependencyProperty.Register( nameof(TemplateButtonCommand), typeof(ICommand), @@ -58,7 +75,7 @@ public static void SetDocumentationType(FrameworkElement target, Type type) => public INavigationView? NavigationView { - get => (INavigationView)GetValue(NavigationViewProperty); + get => (INavigationView?)GetValue(NavigationViewProperty); set => SetValue(NavigationViewProperty, value); } @@ -86,7 +103,9 @@ public PageControlDocumentation() private void OnLoaded() { if (NavigationView is null) + { throw new ArgumentNullException(nameof(NavigationView)); + } NavigationView.Navigated += NavigationViewOnNavigated; } @@ -99,26 +118,26 @@ private void OnUnloaded() private void NavigationViewOnNavigated(NavigationView sender, NavigatedEventArgs args) { - IsDocumentationLinkVisible = Visibility.Collapsed; + SetCurrentValue(IsDocumentationLinkVisibleProperty, Visibility.Collapsed); if (args.Page is not FrameworkElement page || !GetShow(page)) { - Visibility = Visibility.Collapsed; + SetCurrentValue(VisibilityProperty, Visibility.Collapsed); return; } _page = page; - Visibility = Visibility.Visible; + SetCurrentValue(VisibilityProperty, Visibility.Visible); if (GetDocumentationType(page) is not null) { - IsDocumentationLinkVisible = Visibility.Visible; + SetCurrentValue(IsDocumentationLinkVisibleProperty, Visibility.Visible); } } private void OnClick(string? param) { - if (String.IsNullOrWhiteSpace(param) || _page is null) + if (string.IsNullOrWhiteSpace(param) || _page is null) { return; } @@ -136,10 +155,10 @@ private void OnClick(string? param) => CreateUrlForDocumentation(documentationType), "xaml" => CreateUrlForGithub(_page.GetType(), ".xaml"), "c#" => CreateUrlForGithub(_page.GetType(), ".xaml.cs"), - _ => String.Empty + _ => string.Empty }; - if (String.IsNullOrEmpty(navigationUrl)) + if (string.IsNullOrEmpty(navigationUrl)) { return; } @@ -148,7 +167,7 @@ private void OnClick(string? param) { ProcessStartInfo sInfo = new(navigationUrl) { UseShellExecute = true }; - Process.Start(sInfo); + _ = Process.Start(sInfo); } catch (Exception e) { @@ -161,7 +180,7 @@ private static string CreateUrlForGithub(Type pageType, ReadOnlySpan fileE const string baseUrl = "https://github.com/lepoco/wpfui/tree/main/src/Wpf.Ui.Gallery/"; const string baseNamespace = "Wpf.Ui.Gallery"; - var pageFullNameWithoutBaseNamespace = pageType.FullName.AsSpan().Slice(baseNamespace.Length + 1); + ReadOnlySpan pageFullNameWithoutBaseNamespace = pageType.FullName.AsSpan()[(baseNamespace.Length + 1)..]; Span pageUrl = stackalloc char[pageFullNameWithoutBaseNamespace.Length]; pageFullNameWithoutBaseNamespace.CopyTo(pageUrl); @@ -174,19 +193,19 @@ private static string CreateUrlForGithub(Type pageType, ReadOnlySpan fileE } } - return String.Concat(baseUrl, pageUrl, fileExtension); + return string.Concat(baseUrl, pageUrl, fileExtension); } private static string CreateUrlForDocumentation(Type type) { const string baseUrl = "https://wpfui.lepo.co/api/"; - return String.Concat(baseUrl, type.FullName, ".html"); + return string.Concat(baseUrl, type.FullName, ".html"); } private static void SwitchThemes() { - var currentTheme = Wpf.Ui.Appearance.ApplicationThemeManager.GetAppTheme(); + Appearance.ApplicationTheme currentTheme = Wpf.Ui.Appearance.ApplicationThemeManager.GetAppTheme(); Wpf.Ui.Appearance.ApplicationThemeManager.Apply( currentTheme == Wpf.Ui.Appearance.ApplicationTheme.Light diff --git a/src/Wpf.Ui.Gallery/Controls/TermsOfUseContentDialog.xaml.cs b/src/Wpf.Ui.Gallery/Controls/TermsOfUseContentDialog.xaml.cs index 5c3a2e764..2a45ac1be 100644 --- a/src/Wpf.Ui.Gallery/Controls/TermsOfUseContentDialog.xaml.cs +++ b/src/Wpf.Ui.Gallery/Controls/TermsOfUseContentDialog.xaml.cs @@ -10,7 +10,7 @@ namespace Wpf.Ui.Gallery.Controls; public partial class TermsOfUseContentDialog : ContentDialog { - public TermsOfUseContentDialog(ContentPresenter contentPresenter) + public TermsOfUseContentDialog(ContentPresenter? contentPresenter) : base(contentPresenter) { InitializeComponent(); @@ -23,9 +23,8 @@ protected override void OnButtonClick(ContentDialogButton button) base.OnButtonClick(button); return; } - ; - TextBlock.Visibility = Visibility.Visible; - CheckBox.Focus(); + TextBlock.SetCurrentValue(VisibilityProperty, Visibility.Visible); + _ = CheckBox.Focus(); } } diff --git a/src/Wpf.Ui.Gallery/Controls/TypographyControl.xaml.cs b/src/Wpf.Ui.Gallery/Controls/TypographyControl.xaml.cs index bea28d2e3..8969969b0 100644 --- a/src/Wpf.Ui.Gallery/Controls/TypographyControl.xaml.cs +++ b/src/Wpf.Ui.Gallery/Controls/TypographyControl.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. -using System.Windows; using System.Windows.Controls; using Wpf.Ui.Controls; @@ -11,6 +10,7 @@ namespace Wpf.Ui.Gallery.Controls; public class TypographyControl : Control { + /// Identifies the dependency property. public static readonly DependencyProperty ExampleProperty = DependencyProperty.Register( nameof(Example), typeof(string), @@ -18,6 +18,7 @@ public class TypographyControl : Control new PropertyMetadata(string.Empty) ); + /// Identifies the dependency property. public static readonly DependencyProperty ExampleFontTypographyProperty = DependencyProperty.Register( nameof(ExampleFontTypography), typeof(FontTypography), @@ -25,10 +26,12 @@ public class TypographyControl : Control new PropertyMetadata( FontTypography.Body, static (o, args) => - ((TypographyControl)o).OnExampleFontTypographyChanged((FontTypography)args.NewValue) - ) + { + ((TypographyControl)o).OnExampleFontTypographyChanged((FontTypography)args.NewValue); + }) ); + /// Identifies the dependency property. public static readonly DependencyProperty VariableFontProperty = DependencyProperty.Register( nameof(VariableFont), typeof(string), @@ -36,6 +39,7 @@ public class TypographyControl : Control new PropertyMetadata(string.Empty) ); + /// Identifies the dependency property. public static readonly DependencyProperty SizeLinHeightProperty = DependencyProperty.Register( nameof(SizeLinHeight), typeof(string), @@ -43,6 +47,7 @@ public class TypographyControl : Control new PropertyMetadata(string.Empty) ); + /// Identifies the dependency property. public static readonly DependencyProperty FontTypographyStyleProperty = DependencyProperty.Register( nameof(FontTypographyStyle), typeof(string), @@ -70,7 +75,7 @@ public string VariableFont public string SizeLinHeight { - get => (string)GetValue(VariableFontProperty); + get => (string)GetValue(SizeLinHeightProperty); set => SetValue(SizeLinHeightProperty, value); } @@ -82,6 +87,6 @@ public string FontTypographyStyle private void OnExampleFontTypographyChanged(FontTypography fontTypography) { - FontTypographyStyle = fontTypography.ToString(); + SetCurrentValue(FontTypographyStyleProperty, fontTypography.ToString()); } } diff --git a/src/Wpf.Ui.Gallery/ControlsLookup/ControlPages.cs b/src/Wpf.Ui.Gallery/ControlsLookup/ControlPages.cs index 48c4a0cb6..3cf39d7ba 100644 --- a/src/Wpf.Ui.Gallery/ControlsLookup/ControlPages.cs +++ b/src/Wpf.Ui.Gallery/ControlsLookup/ControlPages.cs @@ -5,24 +5,24 @@ namespace Wpf.Ui.Gallery.ControlsLookup; -static class ControlPages +internal static class ControlPages { private const string PageSuffix = "Page"; public static IEnumerable All() { foreach ( - var type in GalleryAssembly + Type? type in GalleryAssembly .Asssembly.GetTypes() .Where(t => t.IsDefined(typeof(GalleryPageAttribute))) ) { - var galleryPageAttribute = type.GetCustomAttributes().FirstOrDefault(); + GalleryPageAttribute? galleryPageAttribute = type.GetCustomAttributes().FirstOrDefault(); if (galleryPageAttribute is not null) { yield return new GalleryPage( - type.Name.Substring(0, type.Name.LastIndexOf(PageSuffix)), + type.Name[..type.Name.LastIndexOf(PageSuffix)], galleryPageAttribute.Description, galleryPageAttribute.Icon, type diff --git a/src/Wpf.Ui.Gallery/ControlsLookup/GalleryPage.cs b/src/Wpf.Ui.Gallery/ControlsLookup/GalleryPage.cs index 119ba603d..10cd73160 100644 --- a/src/Wpf.Ui.Gallery/ControlsLookup/GalleryPage.cs +++ b/src/Wpf.Ui.Gallery/ControlsLookup/GalleryPage.cs @@ -7,4 +7,4 @@ namespace Wpf.Ui.Gallery.ControlsLookup; -record GalleryPage(string Name, string Description, SymbolRegular Icon, Type PageType); +internal record GalleryPage(string Name, string Description, SymbolRegular Icon, Type PageType); diff --git a/src/Wpf.Ui.Gallery/ControlsLookup/GalleryPageAttribute.cs b/src/Wpf.Ui.Gallery/ControlsLookup/GalleryPageAttribute.cs index 95bea27a6..a201ca741 100644 --- a/src/Wpf.Ui.Gallery/ControlsLookup/GalleryPageAttribute.cs +++ b/src/Wpf.Ui.Gallery/ControlsLookup/GalleryPageAttribute.cs @@ -8,9 +8,10 @@ namespace Wpf.Ui.Gallery.ControlsLookup; [AttributeUsage(AttributeTargets.Class)] -class GalleryPageAttribute : Attribute +internal class GalleryPageAttribute : Attribute { public string Description { get; } + public SymbolRegular Icon { get; } public GalleryPageAttribute(string description, SymbolRegular icon) diff --git a/src/Wpf.Ui.Gallery/GalleryAssembly.cs b/src/Wpf.Ui.Gallery/GalleryAssembly.cs index c78340ba0..5173a2183 100644 --- a/src/Wpf.Ui.Gallery/GalleryAssembly.cs +++ b/src/Wpf.Ui.Gallery/GalleryAssembly.cs @@ -5,7 +5,7 @@ namespace Wpf.Ui.Gallery; -class GalleryAssembly +public class GalleryAssembly { public static Assembly Asssembly => Assembly.GetExecutingAssembly(); } diff --git a/src/Wpf.Ui.Gallery/Helpers/NameToPageTypeConverter.cs b/src/Wpf.Ui.Gallery/Helpers/NameToPageTypeConverter.cs index 39fb2f648..da448a069 100644 --- a/src/Wpf.Ui.Gallery/Helpers/NameToPageTypeConverter.cs +++ b/src/Wpf.Ui.Gallery/Helpers/NameToPageTypeConverter.cs @@ -17,6 +17,6 @@ internal sealed class NameToPageTypeConverter { pageName = pageName.Trim().ToLower() + "page"; - return PageTypes.FirstOrDefault(singlePageType => singlePageType.Name.ToLower() == pageName); + return PageTypes.FirstOrDefault(singlePageType => singlePageType.Name.Equals(pageName, StringComparison.CurrentCultureIgnoreCase)); } } diff --git a/src/Wpf.Ui.Gallery/Helpers/PaneDisplayModeToIndexConverter.cs b/src/Wpf.Ui.Gallery/Helpers/PaneDisplayModeToIndexConverter.cs index 6117988c5..23bbf4a9e 100644 --- a/src/Wpf.Ui.Gallery/Helpers/PaneDisplayModeToIndexConverter.cs +++ b/src/Wpf.Ui.Gallery/Helpers/PaneDisplayModeToIndexConverter.cs @@ -11,41 +11,23 @@ internal sealed class PaneDisplayModeToIndexConverter : IValueConverter { public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (value is NavigationViewPaneDisplayMode.LeftFluent) + return value switch { - return 1; - } - - if (value is NavigationViewPaneDisplayMode.Top) - { - return 2; - } - - if (value is NavigationViewPaneDisplayMode.Bottom) - { - return 3; - } - - return 0; + NavigationViewPaneDisplayMode.LeftFluent => 1, + NavigationViewPaneDisplayMode.Top => 2, + NavigationViewPaneDisplayMode.Bottom => 3, + _ => 0 + }; } public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (value is 1) + return value switch { - return NavigationViewPaneDisplayMode.LeftFluent; - } - - if (value is 2) - { - return NavigationViewPaneDisplayMode.Top; - } - - if (value is 3) - { - return NavigationViewPaneDisplayMode.Bottom; - } - - return NavigationViewPaneDisplayMode.Left; + 1 => NavigationViewPaneDisplayMode.LeftFluent, + 2 => NavigationViewPaneDisplayMode.Top, + 3 => NavigationViewPaneDisplayMode.Bottom, + _ => NavigationViewPaneDisplayMode.Left + }; } } diff --git a/src/Wpf.Ui.Gallery/Models/Monaco/MonacoTheme.cs b/src/Wpf.Ui.Gallery/Models/Monaco/MonacoTheme.cs index 7a947e9ec..d0972bab8 100644 --- a/src/Wpf.Ui.Gallery/Models/Monaco/MonacoTheme.cs +++ b/src/Wpf.Ui.Gallery/Models/Monaco/MonacoTheme.cs @@ -8,11 +8,11 @@ namespace Wpf.Ui.Gallery.Models.Monaco; [Serializable] public record MonacoTheme { - public string Base { get; init; } + public string? Base { get; init; } public bool Inherit { get; init; } - public IDictionary Rules { get; init; } + public IDictionary? Rules { get; init; } - public IDictionary Colors { get; init; } + public IDictionary? Colors { get; init; } } diff --git a/src/Wpf.Ui.Gallery/Models/NavigationCard.cs b/src/Wpf.Ui.Gallery/Models/NavigationCard.cs index 55c9ca28b..5eaa79941 100644 --- a/src/Wpf.Ui.Gallery/Models/NavigationCard.cs +++ b/src/Wpf.Ui.Gallery/Models/NavigationCard.cs @@ -9,11 +9,11 @@ namespace Wpf.Ui.Gallery.Models; public record NavigationCard { - public string Name { get; init; } + public string? Name { get; init; } public SymbolRegular Icon { get; init; } - public string Description { get; init; } + public string? Description { get; init; } - public Type PageType { get; init; } + public Type? PageType { get; init; } } diff --git a/src/Wpf.Ui.Gallery/Models/Person.cs b/src/Wpf.Ui.Gallery/Models/Person.cs index 4c7416f17..11dbd7fdd 100644 --- a/src/Wpf.Ui.Gallery/Models/Person.cs +++ b/src/Wpf.Ui.Gallery/Models/Person.cs @@ -11,7 +11,7 @@ public record Person public string LastName { get; init; } - public string Name => FirstName + " " + LastName; + public string Name => $"{FirstName} {LastName}"; public string Company { get; init; } diff --git a/src/Wpf.Ui.Gallery/Models/Product.cs b/src/Wpf.Ui.Gallery/Models/Product.cs index 4fed12368..2f76bc433 100644 --- a/src/Wpf.Ui.Gallery/Models/Product.cs +++ b/src/Wpf.Ui.Gallery/Models/Product.cs @@ -11,9 +11,9 @@ public class Product public int ProductCode { get; set; } - public string ProductName { get; set; } + public string? ProductName { get; set; } - public string QuantityPerUnit { get; set; } + public string? QuantityPerUnit { get; set; } public double UnitPrice { get; set; } diff --git a/src/Wpf.Ui.Gallery/Services/WindowsProviderService.cs b/src/Wpf.Ui.Gallery/Services/WindowsProviderService.cs index 6195d9340..2a795dee6 100644 --- a/src/Wpf.Ui.Gallery/Services/WindowsProviderService.cs +++ b/src/Wpf.Ui.Gallery/Services/WindowsProviderService.cs @@ -18,13 +18,12 @@ public void Show() where T : class { if (!typeof(Window).IsAssignableFrom(typeof(T))) + { throw new InvalidOperationException($"The window class should be derived from {typeof(Window)}."); + } - var windowInstance = _serviceProvider.GetService() as Window; - - if (windowInstance == null) - throw new InvalidOperationException("Window is not registered as service."); - + Window windowInstance = _serviceProvider.GetService() as Window + ?? throw new InvalidOperationException("Window is not registered as service."); windowInstance.Owner = Application.Current.MainWindow; windowInstance.Show(); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/AnchorViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/AnchorViewModel.cs index e2e32330a..f836fa614 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/AnchorViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/AnchorViewModel.cs @@ -16,7 +16,9 @@ public partial class AnchorViewModel : ObservableObject private void OnAnchorCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsAnchorEnabled = !(checkbox?.IsChecked ?? false); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ButtonViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ButtonViewModel.cs index 3355c06e3..517208cd6 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ButtonViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ButtonViewModel.cs @@ -19,7 +19,9 @@ public partial class ButtonViewModel : ObservableObject private void OnSimpleButtonCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsSimpleButtonEnabled = !(checkbox?.IsChecked ?? false); } @@ -28,7 +30,9 @@ private void OnSimpleButtonCheckboxChecked(object sender) private void OnUiButtonCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsUiButtonEnabled = !(checkbox?.IsChecked ?? false); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/CheckBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/CheckBoxViewModel.cs index 6e50f3837..e7fe0ecb6 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/CheckBoxViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/CheckBoxViewModel.cs @@ -25,12 +25,11 @@ public partial class CheckBoxViewModel : ObservableObject private void OnSelectAllChecked(object sender) { if (sender is not CheckBox checkBox) + { return; + } - if (checkBox.IsChecked == null) - checkBox.IsChecked = !( - OptionOneCheckBoxChecked && OptionTwoCheckBoxChecked && OptionThreeCheckBoxChecked - ); + checkBox.IsChecked ??= !OptionOneCheckBoxChecked || !OptionTwoCheckBoxChecked || !OptionThreeCheckBoxChecked; if (checkBox.IsChecked == true) { @@ -49,11 +48,9 @@ private void OnSelectAllChecked(object sender) [RelayCommand] private void OnSingleChecked(string option) { - if (OptionOneCheckBoxChecked && OptionTwoCheckBoxChecked && OptionThreeCheckBoxChecked) - SelectAllCheckBoxChecked = true; - else if (!OptionOneCheckBoxChecked && !OptionTwoCheckBoxChecked && !OptionThreeCheckBoxChecked) - SelectAllCheckBoxChecked = false; - else - SelectAllCheckBoxChecked = null; + bool allChecked = OptionOneCheckBoxChecked && OptionTwoCheckBoxChecked && OptionThreeCheckBoxChecked; + bool allUnchecked = !OptionOneCheckBoxChecked && !OptionTwoCheckBoxChecked && !OptionThreeCheckBoxChecked; + + SelectAllCheckBoxChecked = allChecked ? true : allUnchecked ? false : (bool?)null; } } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ComboBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ComboBoxViewModel.cs index 6e0d1b4ed..f6922aad1 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ComboBoxViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ComboBoxViewModel.cs @@ -8,17 +8,17 @@ namespace Wpf.Ui.Gallery.ViewModels.Pages.BasicInput; public partial class ComboBoxViewModel : ObservableObject { [ObservableProperty] - private IList _comboBoxFontFamilies = new ObservableCollection - { + private ObservableCollection _comboBoxFontFamilies = + [ "Arial", "Comic Sans MS", "Segoe UI", "Times New Roman" - }; + ]; [ObservableProperty] - private IList _comboBoxFontSizes = new ObservableCollection - { + private ObservableCollection _comboBoxFontSizes = + [ 8, 9, 10, @@ -33,5 +33,5 @@ public partial class ComboBoxViewModel : ObservableObject 36, 48, 72 - }; + ]; } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/RadioButtonViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/RadioButtonViewModel.cs index e08251a0a..4bf2bb27e 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/RadioButtonViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/RadioButtonViewModel.cs @@ -16,7 +16,9 @@ public partial class RadioButtonViewModel : ObservableObject private void OnRadioButtonCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsRadioButtonEnabled = !(checkbox?.IsChecked ?? false); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/RatingViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/RatingViewModel.cs index 6b336dca3..ade563762 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/RatingViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/RatingViewModel.cs @@ -25,7 +25,9 @@ public partial class RatingViewModel : ObservableObject private void OnFirstRatingCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsFirstRatingEnabled = !(checkbox?.IsChecked ?? false); } @@ -34,7 +36,9 @@ private void OnFirstRatingCheckboxChecked(object sender) private void OnSecondRatingCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsSecondRatingEnabled = !(checkbox?.IsChecked ?? false); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ThumbRateViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ThumbRateViewModel.cs index 89c1951b9..addd3339a 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ThumbRateViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ThumbRateViewModel.cs @@ -16,13 +16,12 @@ public partial class ThumbRateViewModel : ObservableObject private string _thumRateStateCodeText = ""; private ThumbRateState _thumbRateState = ThumbRateState.Liked; + public ThumbRateState ThumbRateState { get => _thumbRateState; set { - SetProperty(ref _thumbRateState, value); - ThumRateStateText = value switch { ThumbRateState.Liked => "Liked", @@ -30,13 +29,8 @@ public ThumbRateState ThumbRateState _ => "None" }; - ThumRateStateCodeText = - $" "Liked", - ThumbRateState.Disliked => "Disliked", - _ => "None" - })}\" />"; + ThumRateStateCodeText = $""; + _ = SetProperty(ref _thumbRateState, value); } } } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ToggleButtonViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ToggleButtonViewModel.cs index 015b7f12a..35e216ae0 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ToggleButtonViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ToggleButtonViewModel.cs @@ -16,7 +16,9 @@ public partial class ToggleButtonViewModel : ObservableObject private void OnToggleButtonCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsToggleButtonEnabled = !(checkbox?.IsChecked ?? false); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ToggleSwitchViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ToggleSwitchViewModel.cs index 53b67d545..57f3d5dd7 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ToggleSwitchViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/BasicInput/ToggleSwitchViewModel.cs @@ -16,7 +16,9 @@ public partial class ToggleSwitchViewModel : ObservableObject private void OnToggleSwitchCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsToggleSwitchEnabled = !(checkbox?.IsChecked ?? false); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/DataGridViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/DataGridViewModel.cs index 70a4e4156..0622a7f67 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/DataGridViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/DataGridViewModel.cs @@ -17,14 +17,14 @@ public DataGridViewModel() _productsCollection = GenerateProducts(); } - private ObservableCollection GenerateProducts() + private static ObservableCollection GenerateProducts() { var random = new Random(); var products = new ObservableCollection { }; var adjectives = new[] { "Red", "Blueberry" }; var names = new[] { "Marmalade", "Dumplings", "Soup" }; - var units = new[] { "grams", "kilograms", "milliliters" }; + /*var units = new[] { "grams", "kilograms", "milliliters" };*/ for (int i = 0; i < 50; i++) { diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListBoxViewModel.cs index 4a82a5c23..542904522 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListBoxViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListBoxViewModel.cs @@ -12,13 +12,13 @@ public partial class ListBoxViewModel : ObservableObject public ListBoxViewModel() { - _listBoxItems = new ObservableCollection - { + _listBoxItems = + [ "Arial", "Comic Sans MS", "Courier New", "Segoe UI", "Times New Roman" - }; + ]; } } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListViewViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListViewViewModel.cs index 5099d5819..b12c98bf5 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListViewViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Collections/ListViewViewModel.cs @@ -17,7 +17,7 @@ public int ListViewSelectionModeComboBoxSelectedIndex get => _listViewSelectionModeComboBoxSelectedIndex; set { - SetProperty(ref _listViewSelectionModeComboBoxSelectedIndex, value); + _ = SetProperty(ref _listViewSelectionModeComboBoxSelectedIndex, value); UpdateListViewSelectionMode(value); } } @@ -33,7 +33,7 @@ public ListViewViewModel() _basicListViewItems = GeneratePersons(); } - private ObservableCollection GeneratePersons() + private static ObservableCollection GeneratePersons() { var random = new Random(); var persons = new ObservableCollection(); @@ -83,6 +83,7 @@ private ObservableCollection GeneratePersons() }; for (int i = 0; i < 50; i++) + { persons.Add( new Person( names[random.Next(0, names.Length)], @@ -90,6 +91,7 @@ private ObservableCollection GeneratePersons() companies[random.Next(0, companies.Length)] ) ); + } return persons; } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DashboardViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DashboardViewModel.cs index 4aaacf993..60d3d3e00 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DashboardViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DashboardViewModel.cs @@ -19,7 +19,7 @@ public DashboardViewModel(INavigationService navigationService) [RelayCommand] private void OnCardClick(string parameter) { - if (String.IsNullOrWhiteSpace(parameter)) + if (string.IsNullOrWhiteSpace(parameter)) { return; } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DesignGuidance/IconsViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DesignGuidance/IconsViewModel.cs index 796604395..91697eef6 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DesignGuidance/IconsViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DesignGuidance/IconsViewModel.cs @@ -13,41 +13,41 @@ public partial class IconsViewModel : ObservableObject, INavigationAware { private int _selectedIconId = 0; - private string _autoSuggestBoxText = String.Empty; + private string _autoSuggestBoxText = string.Empty; [ObservableProperty] private SymbolRegular _selectedSymbol = SymbolRegular.Empty; [ObservableProperty] - private string _selectedSymbolName = String.Empty; + private string _selectedSymbolName = string.Empty; [ObservableProperty] - private string _selectedSymbolUnicodePoint = String.Empty; + private string _selectedSymbolUnicodePoint = string.Empty; [ObservableProperty] - private string _selectedSymbolTextGlyph = String.Empty; + private string _selectedSymbolTextGlyph = string.Empty; [ObservableProperty] - private string _selectedSymbolXaml = String.Empty; + private string _selectedSymbolXaml = string.Empty; [ObservableProperty] private bool _isIconFilled = false; [ObservableProperty] - private ICollection _iconsCollection = new List(); + private List _iconsCollection = []; [ObservableProperty] - private ICollection _filteredIconsCollection = new DisplayableIcon[] { }; + private List _filteredIconsCollection = []; [ObservableProperty] - private ICollection _iconNames = new string[] { }; + private List _iconNames = []; public string AutoSuggestBoxText { get => _autoSuggestBoxText; set { - SetProperty(ref _autoSuggestBoxText, value); + _ = SetProperty(ref _autoSuggestBoxText, value); UpdateSearchResults(value); } } @@ -64,7 +64,7 @@ public IconsViewModel() foreach (string iconName in names) { - var icon = SymbolGlyph.Parse(iconName); + SymbolRegular icon = SymbolGlyph.Parse(iconName); icons.Add( new DisplayableIcon @@ -80,7 +80,7 @@ public IconsViewModel() IconsCollection = icons; FilteredIconsCollection = icons; - IconNames = icons.Select(icon => icon.Name).ToArray(); + IconNames = icons.Select(icon => icon.Name).ToList(); if (icons.Count > 4) { @@ -107,7 +107,9 @@ public void OnIconSelected(int parameter) public void OnCheckboxChecked(object sender) { if (sender is not CheckBox checkbox) + { return; + } IsIconFilled = checkbox?.IsChecked ?? false; @@ -117,23 +119,25 @@ public void OnCheckboxChecked(object sender) private void UpdateSymbolData() { if (IconsCollection.Count - 1 < _selectedIconId) + { return; + } - var selectedSymbol = IconsCollection.FirstOrDefault(sym => sym.Id == _selectedIconId); + DisplayableIcon selectedSymbol = IconsCollection.FirstOrDefault(sym => sym.Id == _selectedIconId); SelectedSymbol = selectedSymbol.Icon; SelectedSymbolName = selectedSymbol.Name; SelectedSymbolUnicodePoint = selectedSymbol.Code; SelectedSymbolTextGlyph = $"&#x{selectedSymbol.Code};"; SelectedSymbolXaml = - $""; + $""; } private void UpdateSearchResults(string searchedText) { _ = Task.Run(() => { - if (String.IsNullOrEmpty(searchedText)) + if (string.IsNullOrEmpty(searchedText)) { FilteredIconsCollection = IconsCollection; @@ -143,8 +147,8 @@ private void UpdateSearchResults(string searchedText) var formattedText = searchedText.ToLower().Trim(); FilteredIconsCollection = IconsCollection - .Where(icon => icon.Name.ToLower().Contains(formattedText)) - .ToArray(); + .Where(icon => icon.Name.Contains(formattedText, StringComparison.OrdinalIgnoreCase)) + .ToList(); return true; }); diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/ContentDialogViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/ContentDialogViewModel.cs index 18f425d81..1df7fd7a9 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/ContentDialogViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/ContentDialogViewModel.cs @@ -9,15 +9,22 @@ namespace Wpf.Ui.Gallery.ViewModels.Pages.DialogsAndFlyouts; -public partial class ContentDialogViewModel(IContentDialogService contentDialogService) : ObservableObject +public partial class ContentDialogViewModel : ObservableObject { + private readonly IContentDialogService _contentDialogService; + + public ContentDialogViewModel(IContentDialogService contentDialogService) + { + _contentDialogService = contentDialogService; + } + [ObservableProperty] - private string _dialogResultText = String.Empty; + private string _dialogResultText = string.Empty; [RelayCommand] private async Task OnShowDialog(object content) { - ContentDialogResult result = await contentDialogService.ShowSimpleDialogAsync( + ContentDialogResult result = await _contentDialogService.ShowSimpleDialogAsync( new SimpleContentDialogCreateOptions() { Title = "Save your work?", @@ -39,7 +46,7 @@ private async Task OnShowDialog(object content) [RelayCommand] private async Task OnShowSignInContentDialog() { - var termsOfUseContentDialog = new TermsOfUseContentDialog(contentDialogService.GetContentPresenter()); + var termsOfUseContentDialog = new TermsOfUseContentDialog(_contentDialogService.GetDialogHost()); _ = await termsOfUseContentDialog.ShowAsync(); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/FlyoutViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/FlyoutViewModel.cs index e9a1d3814..c72c3be78 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/FlyoutViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/FlyoutViewModel.cs @@ -14,6 +14,8 @@ public partial class FlyoutViewModel : ObservableObject private void OnButtonClick(object sender) { if (!IsFlyoutOpen) + { IsFlyoutOpen = true; + } } } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/MessageBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/MessageBoxViewModel.cs index 719779f30..7a527c79e 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/MessageBoxViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/MessageBoxViewModel.cs @@ -3,18 +3,22 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. +using System.Diagnostics.CodeAnalysis; + namespace Wpf.Ui.Gallery.ViewModels.Pages.DialogsAndFlyouts; public partial class MessageBoxViewModel : ObservableObject { + [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "relay command")] [RelayCommand] private void OnOpenStandardMessageBox(object sender) { - System.Windows.MessageBox.Show("Something about to happen", "I can feel it"); + _ = MessageBox.Show("Something about to happen", "I can feel it"); } + [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "relay command")] [RelayCommand] - private async void OnOpenCustomMessageBox(object sender) + private async Task OnOpenCustomMessageBox(object sender) { var uiMessageBox = new Wpf.Ui.Controls.MessageBox { @@ -23,6 +27,6 @@ private async void OnOpenCustomMessageBox(object sender) "Never gonna give you up, never gonna let you down Never gonna run around and desert you Never gonna make you cry, never gonna say goodbye", }; - var result = await uiMessageBox.ShowDialogAsync(); + _ = await uiMessageBox.ShowDialogAsync(); } } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/SnackbarViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/SnackbarViewModel.cs index 9738cf04d..8279746ff 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/SnackbarViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/DialogsAndFlyouts/SnackbarViewModel.cs @@ -21,7 +21,7 @@ public int SnackbarAppearanceComboBoxSelectedIndex get => _snackbarAppearanceComboBoxSelectedIndex; set { - SetProperty(ref _snackbarAppearanceComboBoxSelectedIndex, value); + _ = SetProperty(ref _snackbarAppearanceComboBoxSelectedIndex, value); UpdateSnackbarAppearance(value); } } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/BreadcrumbBarViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/BreadcrumbBarViewModel.cs index 922cb1026..67c75fbf4 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/BreadcrumbBarViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/BreadcrumbBarViewModel.cs @@ -9,17 +9,17 @@ namespace Wpf.Ui.Gallery.ViewModels.Pages.Navigation; public partial class BreadcrumbBarViewModel : ObservableObject { - private readonly IEnumerable _baseFoldersCollection = new Folder[] - { + private readonly Folder[] _baseFoldersCollection = + [ new("Home"), new("Folder1"), new("Folder2"), new("Folder3"), - }; + ]; [ObservableProperty] - private ObservableCollection _strings = new ObservableCollection - { + private ObservableCollection _strings = + [ "Home", "Document", "Design", @@ -28,10 +28,10 @@ public partial class BreadcrumbBarViewModel : ObservableObject "Folder1", "Folder2", "Folder3" - }; + ]; [ObservableProperty] - private ObservableCollection _folders = new ObservableCollection { }; + private ObservableCollection _folders = new(); public BreadcrumbBarViewModel() { @@ -45,17 +45,21 @@ private void OnStringSelected(object item) { } private void OnFolderSelected(object item) { if (item is not Folder selectedFolder) + { return; + } var index = Folders.IndexOf(selectedFolder); Folders.Clear(); var counter = 0; - foreach (var folder in _baseFoldersCollection) + foreach (Folder folder in _baseFoldersCollection) { if (counter++ > index) + { break; + } Folders.Add(folder); } @@ -71,7 +75,9 @@ private void ResetFoldersCollection() { Folders.Clear(); - foreach (var folder in _baseFoldersCollection) + foreach (Folder folder in _baseFoldersCollection) + { Folders.Add(folder); + } } } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/FilePickerViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/FilePickerViewModel.cs index 2ab878efd..4cfb59363 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/FilePickerViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/OpSystem/FilePickerViewModel.cs @@ -13,37 +13,37 @@ public partial class FilePickerViewModel : ObservableObject private Visibility _openedFilePathVisibility = Visibility.Collapsed; [ObservableProperty] - private string _openedFilePath = String.Empty; + private string _openedFilePath = string.Empty; [ObservableProperty] private Visibility _openedPicturePathVisibility = Visibility.Collapsed; [ObservableProperty] - private string _openedPicturePath = String.Empty; + private string _openedPicturePath = string.Empty; [ObservableProperty] private Visibility _openedMultiplePathVisibility = Visibility.Collapsed; [ObservableProperty] - private string _openedMultiplePath = String.Empty; + private string _openedMultiplePath = string.Empty; [ObservableProperty] private Visibility _openedFolderPathVisibility = Visibility.Collapsed; [ObservableProperty] - private string _openedFolderPath = String.Empty; + private string _openedFolderPath = string.Empty; [ObservableProperty] - private string _fileToSaveName = String.Empty; + private string _fileToSaveName = string.Empty; [ObservableProperty] - private string _fileToSaveContents = String.Empty; + private string _fileToSaveContents = string.Empty; [ObservableProperty] private Visibility _savedFileNoticeVisibility = Visibility.Collapsed; [ObservableProperty] - private string _savedFileNotice = String.Empty; + private string _savedFileNotice = string.Empty; [RelayCommand] public void OnOpenFile() @@ -122,7 +122,7 @@ public void OnOpenMultiple() var fileNames = openFileDialog.FileNames; - OpenedMultiplePath = String.Join("\n", fileNames); + OpenedMultiplePath = string.Join("\n", fileNames); OpenedMultiplePathVisibility = Visibility.Visible; } @@ -149,7 +149,7 @@ public void OnOpenFolder() return; } - OpenedFolderPath = String.Join("\n", openFolderDialog.FolderNames); + OpenedFolderPath = string.Join("\n", openFolderDialog.FolderNames); OpenedFolderPathVisibility = Visibility.Visible; #else OpenedFolderPath = "OpenFolderDialog requires .NET 8 or newer"; @@ -169,12 +169,12 @@ public async Task OnSaveFile(CancellationToken cancellation) InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) }; - if (!String.IsNullOrEmpty(FileToSaveName)) + if (!string.IsNullOrEmpty(FileToSaveName)) { var invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); - saveFileDialog.FileName = String + saveFileDialog.FileName = string .Join( "_", FileToSaveName.Split(invalidChars.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/SettingsViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/SettingsViewModel.cs index 59b3c2556..5c679b4be 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/SettingsViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/SettingsViewModel.cs @@ -16,7 +16,7 @@ public sealed partial class SettingsViewModel : ObservableObject, INavigationAwa private bool _isInitialized = false; [ObservableProperty] - private string _appVersion = String.Empty; + private string _appVersion = string.Empty; [ObservableProperty] private ApplicationTheme _currentApplicationTheme = ApplicationTheme.Unknown; @@ -72,8 +72,8 @@ private void OnThemeChanged(ApplicationTheme currentApplicationTheme, Color syst } } - private string GetAssemblyVersion() + private static string GetAssemblyVersion() { - return Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? String.Empty; + return Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty; } } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBadgeViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBadgeViewModel.cs index e0066d79b..6d5885c0b 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBadgeViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBadgeViewModel.cs @@ -24,7 +24,7 @@ public int InfoBadgeSeverityComboBoxSelectedIndex } } - private InfoBadgeSeverity ConvertIndexToInfoBadgeSeverity(int value) + private static InfoBadgeSeverity ConvertIndexToInfoBadgeSeverity(int value) { return value switch { diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBarViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBarViewModel.cs index a2664617e..c420d64a1 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBarViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/StatusAndInfo/InfoBarViewModel.cs @@ -22,30 +22,32 @@ public partial class InfoBarViewModel : ObservableObject private InfoBarSeverity _longInfoBarSeverity = InfoBarSeverity.Informational; private int _shortInfoBarSeverityComboBoxSelectedIndex = 0; + public int ShortInfoBarSeverityComboBoxSelectedIndex { get => _shortInfoBarSeverityComboBoxSelectedIndex; set { - SetProperty(ref _shortInfoBarSeverityComboBoxSelectedIndex, value); + _ = SetProperty(ref _shortInfoBarSeverityComboBoxSelectedIndex, value); ShortInfoBarSeverity = ConvertIndexToInfoBarSeverity(value); } } private int _longInfoBarSeverityComboBoxSelectedIndex = 0; + public int LongInfoBarSeverityComboBoxSelectedIndex { get => _longInfoBarSeverityComboBoxSelectedIndex; set { - SetProperty(ref _longInfoBarSeverityComboBoxSelectedIndex, value); + _ = SetProperty(ref _longInfoBarSeverityComboBoxSelectedIndex, value); LongInfoBarSeverity = ConvertIndexToInfoBarSeverity(value); } } - private InfoBarSeverity ConvertIndexToInfoBarSeverity(int value) + private static InfoBarSeverity ConvertIndexToInfoBarSeverity(int value) { return value switch { diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/AutoSuggestBoxViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/AutoSuggestBoxViewModel.cs index 2dc435802..896eed170 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/AutoSuggestBoxViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Text/AutoSuggestBoxViewModel.cs @@ -8,7 +8,7 @@ namespace Wpf.Ui.Gallery.ViewModels.Pages.Text; public partial class AutoSuggestBoxViewModel : ObservableObject { [ObservableProperty] - private IEnumerable _autoSuggestBoxSuggestions = new[] + private List _autoSuggestBoxSuggestions = new() { "John", "Winston", diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Windows/WindowsViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Windows/WindowsViewModel.cs index 79a265891..742e8beae 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Windows/WindowsViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Windows/WindowsViewModel.cs @@ -13,19 +13,19 @@ namespace Wpf.Ui.Gallery.ViewModels.Pages.Windows; public partial class WindowsViewModel(WindowsProviderService windowsProviderService) : ObservableObject { [ObservableProperty] - private IEnumerable _windowCards = new WindowCard[] - { + private WindowCard[] _windowCards = + [ new("Monaco", "Visual Studio Code in your WPF app.", SymbolRegular.CodeBlock24, "monaco"), new("Editor", "Text editor with tabbed background.", SymbolRegular.ScanText24, "editor"), #if DEBUG new("Sandbox", "Sandbox for controls testing.", SymbolRegular.ScanText24, "sandbox"), #endif - }; + ]; [RelayCommand] public void OnOpenWindow(string value) { - if (String.IsNullOrEmpty(value)) + if (string.IsNullOrEmpty(value)) { return; } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs index e45879a95..f49592479 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs @@ -28,8 +28,8 @@ public partial class MainWindowViewModel : ObservableObject private string _applicationTitle = "WPF UI Gallery"; [ObservableProperty] - private ICollection _menuItems = new ObservableCollection - { + private ObservableCollection _menuItems = + [ new NavigationViewItem("Home", SymbolRegular.Home24, typeof(DashboardPage)), new NavigationViewItem() { @@ -171,19 +171,18 @@ public partial class MainWindowViewModel : ObservableObject } }, new NavigationViewItem("Windows", SymbolRegular.WindowApps24, typeof(WindowsPage)) - }; + ]; [ObservableProperty] - private ICollection _footerMenuItems = new ObservableCollection() - { + private ObservableCollection _footerMenuItems = + [ new NavigationViewItem("Settings", SymbolRegular.Settings24, typeof(SettingsPage)) - }; + ]; [ObservableProperty] private ObservableCollection _trayMenuItems = - new() - { - new Wpf.Ui.Controls.MenuItem { Header = "Home", Tag = "tray_home" }, - new Wpf.Ui.Controls.MenuItem { Header = "Close", Tag = "tray_close" } - }; + [ + new Wpf.Ui.Controls.MenuItem { Header = "Home", Tag = "tray_home" }, + new Wpf.Ui.Controls.MenuItem { Header = "Close", Tag = "tray_close" } + ]; } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Windows/MonacoWindowViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Windows/MonacoWindowViewModel.cs index 1517e700c..799878919 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Windows/MonacoWindowViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Windows/MonacoWindowViewModel.cs @@ -17,11 +17,11 @@ public partial class MonacoWindowViewModel : ObservableObject public void SetWebView(WebView2 webView) { webView.NavigationCompleted += OnWebViewNavigationCompleted; - webView.UseLayoutRounding = true; - webView.DefaultBackgroundColor = System.Drawing.Color.Transparent; - webView.Source = new Uri( + webView.SetCurrentValue(FrameworkElement.UseLayoutRoundingProperty, true); + webView.SetCurrentValue(WebView2.DefaultBackgroundColorProperty, System.Drawing.Color.Transparent); + webView.SetCurrentValue(WebView2.SourceProperty, new Uri( System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"Assets\Monaco\index.html") - ); + )); _monacoController = new MonacoController(webView); } @@ -52,7 +52,7 @@ Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e DispatchAsync(InitializeEditorAsync); } - private DispatcherOperation DispatchAsync(Func callback) + private static DispatcherOperation DispatchAsync(Func callback) { return Application.Current.Dispatcher.InvokeAsync(callback); } diff --git a/src/Wpf.Ui.Gallery/ViewModels/Windows/SandboxWindowViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Windows/SandboxWindowViewModel.cs index 57011bb4a..2ebbc22bb 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Windows/SandboxWindowViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Windows/SandboxWindowViewModel.cs @@ -8,5 +8,5 @@ namespace Wpf.Ui.Gallery.ViewModels.Windows; public partial class SandboxWindowViewModel : ObservableObject { [ObservableProperty] - public string? _autoSuggestBoxText; + private string? _autoSuggestBoxText; } diff --git a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/ContentDialog.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/ContentDialog.xaml.cs index be60b6e58..ce58619bd 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/ContentDialog.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/ContentDialog.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.DialogsAndFlyouts; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/DialogsAndFlyoutsPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/DialogsAndFlyoutsPage.xaml.cs index f1c0640b0..66a162779 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/DialogsAndFlyoutsPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/DialogsAndFlyoutsPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ViewModels.Pages.DialogsAndFlyouts; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/FlyoutPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/FlyoutPage.xaml.cs index c7d3b6625..463f5bd36 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/FlyoutPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/FlyoutPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.DialogsAndFlyouts; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/MessageBoxPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/MessageBoxPage.xaml.cs index 9f69c5b96..5fc81e8d1 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/MessageBoxPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/MessageBoxPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.DialogsAndFlyouts; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/SnackbarPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/SnackbarPage.xaml.cs index 33c1b8662..cdf8ea319 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/SnackbarPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/DialogsAndFlyouts/SnackbarPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ViewModels.Pages.DialogsAndFlyouts; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Layout/CardActionPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Layout/CardActionPage.xaml.cs index 4715e9817..ab41da6d3 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Layout/CardActionPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/Layout/CardActionPage.xaml.cs @@ -3,20 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.Layout; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Layout/LayoutPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Layout/LayoutPage.xaml.cs index 125c16a9b..c5a7469e7 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Layout/LayoutPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/Layout/LayoutPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ViewModels.Pages.Layout; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Text/LabelPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Text/LabelPage.xaml.cs index 519d6e82b..12e94dc9b 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Text/LabelPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/Text/LabelPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.Text; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Text/NumberBoxPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Text/NumberBoxPage.xaml.cs index f0df69a10..cfd1aab94 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Text/NumberBoxPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/Text/NumberBoxPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.Text; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Text/PasswordBoxPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Text/PasswordBoxPage.xaml.cs index d44310ffb..9989f9579 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Text/PasswordBoxPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/Text/PasswordBoxPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.Text; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Text/RichTextBoxPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Text/RichTextBoxPage.xaml.cs index 97c35fd8f..fb24632e6 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Text/RichTextBoxPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/Text/RichTextBoxPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.Text; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBlockPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBlockPage.xaml.cs index 164c43ca2..25476cfd1 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBlockPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBlockPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.Text; diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml.cs index 25cadbcc0..a6fb31045 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml.cs @@ -3,7 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - using Wpf.Ui.Controls; using Wpf.Ui.Gallery.ControlsLookup; using Wpf.Ui.Gallery.ViewModels.Pages.Text; diff --git a/src/Wpf.Ui.Gallery/Views/Windows/EditorWindow.xaml.cs b/src/Wpf.Ui.Gallery/Views/Windows/EditorWindow.xaml.cs index ecce5d38b..9d7ddf38c 100644 --- a/src/Wpf.Ui.Gallery/Views/Windows/EditorWindow.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Windows/EditorWindow.xaml.cs @@ -19,203 +19,197 @@ public EditorWindow(EditorWindowViewModel viewModel) InitializeComponent(); } - // internal class EditorDataStack : INotifyPropertyChanged - // { - // public event PropertyChangedEventHandler PropertyChanged; - - // protected void OnPropertyChanged(string name) - // { - // PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); - // } - - // private int - // _line = 1, - // _character = 0, - // _progress = 80; - - // private string _file = "Draft"; - - // public int Line - // { - // get => _line; - // set - // { - // if (value == _line) - // return; - // _line = value; - // OnPropertyChanged(nameof(Line)); - // } - // } - - // public int Character - // { - // get => _character; - // set - // { - // if (value == _character) - // return; - // _character = value; - // OnPropertyChanged(nameof(Character)); - // } - // } - - // public int Progress - // { - // get => _progress; - // set - // { - // if (value == _progress) - // return; - // _progress = value; - // OnPropertyChanged(nameof(Progress)); - // } - // } - - // public string File - // { - // get => _file; - // set - // { - // if (value == _file) - // return; - // _file = value; - // OnPropertyChanged(nameof(File)); - // } - // } - // } - - // private EditorDataStack DataStack = new(); - - // public string Line { get; set; } = "0"; - - // public EditorWindow(EditorWindowViewModel viewModel) - // { - // ViewModel = viewModel; - - // InitializeComponent(); - - // DataContext = DataStack; - // } - - // private void MenuItem_OnClick(object sender, RoutedEventArgs e) - // { - // if (sender is not MenuItem item) - // return; - - // string tag = item?.Tag as string ?? String.Empty; - - //#if DEBUG - // System.Diagnostics.Debug.WriteLine("DEBUG | Clicked: " + tag, "Wpf.Ui.Demo"); - //#endif - - // switch (tag) - // { - // case "exit": - // Close(); - - // break; - - // case "save": - // Save(); - - // break; - - // case "open": - // Open(); - - // break; - - // case "new_file": - // RootTextBox.Document = new(); - // DataStack.File = "Draft"; - - // break; - - // case "new_window": - // EditorWindow editorWindow = new(ViewModel); - // editorWindow.Owner = this; - // editorWindow.Show(); - - // break; - - // case "word_wrap": - // RootSnackbar.Title = "Word wrapping changed!"; - // RootSnackbar.Message = "Currently word wrapping is " + (item.IsChecked ? "Enabled" : "Disabled"); - // RootSnackbar.Show(); - - // break; - - // case "status_bar": - // RootStatusBar.Visibility = item.IsChecked ? Visibility.Visible : Visibility.Collapsed; - - // break; - - // default: - // ActionDialog.Show(); - - // break; - // } - // } - - // private void Save() - // { - // OpenFileDialog openFileDialog = new OpenFileDialog(); - // if (openFileDialog.ShowDialog() == true) - // { - // DataStack.File = openFileDialog.FileName; - // // Save - // } - // } - - // private void Open() - // { - // OpenFileDialog openFileDialog = new OpenFileDialog(); - // if (openFileDialog.ShowDialog() == true) - // { - // DataStack.File = openFileDialog.FileName; - // // Load - // } - // } - - // private void UpdateLine() - // { - // TextPointer caretPosition = RootTextBox.CaretPosition; - // TextPointer p = RootTextBox.Document.ContentStart.GetLineStartPosition(0); - - // RootTextBox.CaretPosition.GetLineStartPosition(-Int32.MaxValue, out int lineMoved); + /* + internal class EditorDataStack : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + protected void OnPropertyChanged(string name) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); + } + + private int + _line = 1, + _character = 0, + _progress = 80; + + private string _file = "Draft"; + + public int Line + { + get => _line; + set + { + if (value == _line) + return; + _line = value; + OnPropertyChanged(nameof(Line)); + } + } + + public int Character + { + get => _character; + set + { + if (value == _character) + return; + _character = value; + OnPropertyChanged(nameof(Character)); + } + } + + public int Progress + { + get => _progress; + set + { + if (value == _progress) + return; + _progress = value; + OnPropertyChanged(nameof(Progress)); + } + } + + public string File + { + get => _file; + set + { + if (value == _file) + return; + _file = value; + OnPropertyChanged(nameof(File)); + } + } + } + + private EditorDataStack DataStack = new(); + + public string Line { get; set; } = "0"; + + public EditorWindow(EditorWindowViewModel viewModel) + { + ViewModel = viewModel; + + InitializeComponent(); + + DataContext = DataStack; + } + + private void MenuItem_OnClick(object sender, RoutedEventArgs e) + { + if (sender is not MenuItem item) + return; + + string tag = item?.Tag as string ?? String.Empty; + + System.Diagnostics.Debug.WriteLine("DEBUG | Clicked: " + tag, "Wpf.Ui.Demo"); + + switch (tag) + { + case "exit": + Close(); + + break; + + case "save": + Save(); + + break; + + case "open": + Open(); + + break; + + case "new_file": + RootTextBox.Document = new(); + DataStack.File = "Draft"; + + break; + + case "new_window": + EditorWindow editorWindow = new(ViewModel); + editorWindow.Owner = this; + editorWindow.Show(); + + break; + + case "word_wrap": + RootSnackbar.Title = "Word wrapping changed!"; + RootSnackbar.Message = "Currently word wrapping is " + (item.IsChecked ? "Enabled" : "Disabled"); + RootSnackbar.Show(); + + break; - // DataStack.Line = -lineMoved; - // DataStack.Character = Math.Max(p.GetOffsetToPosition(caretPosition) - 1, 0); - // } - - // private void RootTextBox_OnGotFocus(object sender, RoutedEventArgs e) - // { - //#if DEBUG - // System.Diagnostics.Debug.WriteLine("DEBUG | Editor got focus", "Wpf.Ui.Demo.Editor"); - //#endif - // UpdateLine(); - // } - - // private void RootTextBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e) - // { - // if (e.ClickCount > 2) - // return; - //#if DEBUG - // System.Diagnostics.Debug.WriteLine("DEBUG | Editor mouse down", "Wpf.Ui.Demo.Editor"); - //#endif - // UpdateLine(); - // } - - // private void RootTextBox_OnPreviewKeyUp(object sender, KeyEventArgs e) - // { - //#if DEBUG - // System.Diagnostics.Debug.WriteLine("DEBUG | Editor key up", "Wpf.Ui.Demo.Editor"); - //#endif - // UpdateLine(); - // } - - // private void ActionDialog_OnButtonRightClick(object sender, RoutedEventArgs e) - // { - // ActionDialog.Hide(); - // } + case "status_bar": + RootStatusBar.Visibility = item.IsChecked ? Visibility.Visible : Visibility.Collapsed; + + break; + + default: + ActionDialog.Show(); + + break; + } + } + + private void Save() + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + if (openFileDialog.ShowDialog() == true) + { + DataStack.File = openFileDialog.FileName; + // Save + } + } + + private void Open() + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + if (openFileDialog.ShowDialog() == true) + { + DataStack.File = openFileDialog.FileName; + // Load + } + } + + private void UpdateLine() + { + TextPointer caretPosition = RootTextBox.CaretPosition; + TextPointer p = RootTextBox.Document.ContentStart.GetLineStartPosition(0); + + RootTextBox.CaretPosition.GetLineStartPosition(-Int32.MaxValue, out int lineMoved); + + DataStack.Line = -lineMoved; + DataStack.Character = Math.Max(p.GetOffsetToPosition(caretPosition) - 1, 0); + } + + private void RootTextBox_OnGotFocus(object sender, RoutedEventArgs e) + { + System.Diagnostics.Debug.WriteLine("DEBUG | Editor got focus", "Wpf.Ui.Demo.Editor"); + UpdateLine(); + } + + private void RootTextBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e) + { + if (e.ClickCount > 2) + return; + System.Diagnostics.Debug.WriteLine("DEBUG | Editor mouse down", "Wpf.Ui.Demo.Editor"); + UpdateLine(); + } + + private void RootTextBox_OnPreviewKeyUp(object sender, KeyEventArgs e) + { + System.Diagnostics.Debug.WriteLine("DEBUG | Editor key up", "Wpf.Ui.Demo.Editor"); + UpdateLine(); + } + + private void ActionDialog_OnButtonRightClick(object sender, RoutedEventArgs e) + { + ActionDialog.Hide(); + } + */ } diff --git a/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml.cs b/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml.cs index c6162052f..d4525dae5 100644 --- a/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml.cs @@ -29,7 +29,7 @@ IContentDialogService contentDialogService snackbarService.SetSnackbarPresenter(SnackbarPresenter); navigationService.SetNavigationControl(NavigationView); - contentDialogService.SetContentPresenter(RootContentDialog); + contentDialogService.SetDialogHost(RootContentDialog); NavigationView.SetServiceProvider(serviceProvider); } @@ -47,10 +47,12 @@ private void OnNavigationSelectionChanged(object sender, RoutedEventArgs e) return; } - NavigationView.HeaderVisibility = + NavigationView.SetCurrentValue( + NavigationView.HeaderVisibilityProperty, navigationView.SelectedItem?.TargetPageType != typeof(DashboardPage) ? Visibility.Visible - : Visibility.Collapsed; + : Visibility.Collapsed + ); } private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) @@ -61,7 +63,7 @@ private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) } _isPaneOpenedOrClosedFromCode = true; - NavigationView.IsPaneOpen = !(e.NewSize.Width <= 1200); + NavigationView.SetCurrentValue(NavigationView.IsPaneOpenProperty, e.NewSize.Width > 1200); _isPaneOpenedOrClosedFromCode = false; } diff --git a/src/Wpf.Ui.Gallery/Views/Windows/SandboxWindow.xaml.cs b/src/Wpf.Ui.Gallery/Views/Windows/SandboxWindow.xaml.cs index 9200ac630..1046f73bb 100644 --- a/src/Wpf.Ui.Gallery/Views/Windows/SandboxWindow.xaml.cs +++ b/src/Wpf.Ui.Gallery/Views/Windows/SandboxWindow.xaml.cs @@ -22,16 +22,19 @@ public SandboxWindow(SandboxWindowViewModel viewModel) MyTestNavigationView.Loaded += (sender, args) => { - MyTestNavigationView.MenuItemsSource = new ObservableCollection() - { - new NavigationViewItem("Home", SymbolRegular.Home24, typeof(SamplePage1)) - }; + MyTestNavigationView.SetCurrentValue( + NavigationView.MenuItemsSourceProperty, + new ObservableCollection() + { + new NavigationViewItem("Home", SymbolRegular.Home24, typeof(SamplePage1)) + } + ); var configurationBasedLogic = true; if (configurationBasedLogic) { - MyTestNavigationView.MenuItems.Add( + _ = MyTestNavigationView.MenuItems.Add( new NavigationViewItem("Test", SymbolRegular.Home24, typeof(SamplePage2)) ); } diff --git a/src/Wpf.Ui.Gallery/Wpf.Ui.Gallery.csproj b/src/Wpf.Ui.Gallery/Wpf.Ui.Gallery.csproj index 24c428ff6..455aaf086 100644 --- a/src/Wpf.Ui.Gallery/Wpf.Ui.Gallery.csproj +++ b/src/Wpf.Ui.Gallery/Wpf.Ui.Gallery.csproj @@ -12,6 +12,7 @@ AnyCPU;x64;x86 10.0.18362.0 $(NoWarn);SA1601 + True diff --git a/src/Wpf.Ui.SyntaxHighlight/Controls/CodeBlock.cs b/src/Wpf.Ui.SyntaxHighlight/Controls/CodeBlock.cs index 356091c82..924712579 100644 --- a/src/Wpf.Ui.SyntaxHighlight/Controls/CodeBlock.cs +++ b/src/Wpf.Ui.SyntaxHighlight/Controls/CodeBlock.cs @@ -16,11 +16,9 @@ namespace Wpf.Ui.SyntaxHighlight.Controls; /// /// Formats and display a fragment of the source code. /// -//[ToolboxItem(true)] -//[ToolboxBitmap(typeof(CodeBlock), "CodeBlock.bmp")] public class CodeBlock : System.Windows.Controls.ContentControl { - private string _sourceCode = String.Empty; + private string _sourceCode = string.Empty; /// /// Property for . diff --git a/src/Wpf.Ui.SyntaxHighlight/Highlighter.cs b/src/Wpf.Ui.SyntaxHighlight/Highlighter.cs index 498d5d709..47f3ba5e0 100644 --- a/src/Wpf.Ui.SyntaxHighlight/Highlighter.cs +++ b/src/Wpf.Ui.SyntaxHighlight/Highlighter.cs @@ -2,6 +2,8 @@ // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. +// +// TODO: This class is work in progress. using System; using System.Linq; @@ -12,8 +14,6 @@ namespace Wpf.Ui.SyntaxHighlight; -// TODO: This class is work in progress. - /// /// Formats a string of code into control. /// Implementation and regex patterns inspired by . @@ -38,17 +38,17 @@ internal static class Highlighter private const string EntityPattern = /* language=regex */ @"(&[a-zA-Z0-9#]+;)"; - private const string PunctuationPattern = /* language=regex */ - @"(!==?|(?:[[\\] ()\{\}.:;,+\\-?=!]|<|>)+|&&|\\|\\|)"; + //private const string PunctuationPattern = /* language=regex */ + // @"(!==?|(?:[[\\] ()\{\}.:;,+\\-?=!]|<|>)+|&&|\\|\\|)"; - private const string NumberPattern = /* language=regex */ - @"(-? (?:\.\d+|\d+(?:\.\d+)?))"; + //private const string NumberPattern = /* language=regex */ + // @"(-? (?:\.\d+|\d+(?:\.\d+)?))"; - private const string BooleanPattern = /* language=regex */ - "\b(true|false)\b"; + //private const string BooleanPattern = /* language=regex */ + // "\b(true|false)\b"; - private const string AttributePattern = /* language=regex */ - "(\\s*)([a-zA-Z\\d\\-:]+)=(\" | ')(.*?)\\3"; + //private const string AttributePattern = /* language=regex */ + // "(\\s*)([a-zA-Z\\d\\-:]+)=(\" | ')(.*?)\\3"; public static Paragraph FormatAsParagraph( string code, @@ -60,22 +60,26 @@ public static Paragraph FormatAsParagraph( bool lightTheme = IsLightTheme(); - foreach (Match match in rgx.Matches(code)) + foreach (Match match in rgx.Matches(code).Cast()) { foreach (object group in match.Groups) { // Remove whole matches if (group is Match) + { continue; + } // Cast to group Group codeMatched = (Group)group; // Remove empty groups - if (String.IsNullOrEmpty(codeMatched.Value)) + if (string.IsNullOrEmpty(codeMatched.Value)) + { continue; + } - if (codeMatched.Value.Contains("\t")) + if (codeMatched.Value.Contains('\t')) { paragraph.Inlines.Add(Line(" ", Brushes.Transparent)); } @@ -83,13 +87,13 @@ public static Paragraph FormatAsParagraph( { paragraph.Inlines.Add(Line(codeMatched.Value, Brushes.Orange)); } - else if (codeMatched.Value.Contains("<") || codeMatched.Value.Contains(">")) + else if (codeMatched.Value.Contains('<') || codeMatched.Value.Contains('>')) { paragraph.Inlines.Add( Line(codeMatched.Value, lightTheme ? Brushes.DarkCyan : Brushes.CornflowerBlue) ); } - else if (codeMatched.Value.Contains("\"")) + else if (codeMatched.Value.Contains('"')) { string[] attributeArray = codeMatched.Value.Split('"'); attributeArray = attributeArray.Where(x => !string.IsNullOrEmpty(x.Trim())).ToArray(); @@ -120,7 +124,7 @@ public static Paragraph FormatAsParagraph( ); } } - else if (codeMatched.Value.Contains("'")) + else if (codeMatched.Value.Contains('\'')) { string[] attributeArray = codeMatched.Value.Split('\''); attributeArray = attributeArray.Where(x => !string.IsNullOrEmpty(x.Trim())).ToArray(); @@ -186,18 +190,23 @@ private static bool IsLightTheme() return Appearance.ApplicationThemeManager.GetAppTheme() == ApplicationTheme.Light; } + /* private static string GetPattern(SyntaxLanguage language) { - return GetPattern(language, String.Empty); + return GetPattern(language, string.Empty); } + */ + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "WIP")] private static string GetPattern(SyntaxLanguage language, string code) { - var pattern = String.Empty; + var pattern = string.Empty; // TODO: Auto detected if (language == SyntaxLanguage.Autodetect) + { language = SyntaxLanguage.XAML; + } switch (language) { diff --git a/src/Wpf.Ui.ToastNotifications/Wpf.Ui.ToastNotifications.csproj b/src/Wpf.Ui.ToastNotifications/Wpf.Ui.ToastNotifications.csproj index b6a4fe510..8938f9db1 100644 --- a/src/Wpf.Ui.ToastNotifications/Wpf.Ui.ToastNotifications.csproj +++ b/src/Wpf.Ui.ToastNotifications/Wpf.Ui.ToastNotifications.csproj @@ -54,6 +54,7 @@ true true false + True diff --git a/src/Wpf.Ui.Tray/Controls/NotifyIcon.cs b/src/Wpf.Ui.Tray/Controls/NotifyIcon.cs index 0c187ef16..7bc0fcac7 100644 --- a/src/Wpf.Ui.Tray/Controls/NotifyIcon.cs +++ b/src/Wpf.Ui.Tray/Controls/NotifyIcon.cs @@ -28,50 +28,35 @@ namespace Wpf.Ui.Tray.Controls; /// </tray:NotifyIcon> /// /// -//[ToolboxItem(true)] -//[ToolboxBitmap(typeof(NotifyIcon), "NotifyIcon.bmp")] -public class NotifyIcon : System.Windows.FrameworkElement +public class NotifyIcon : System.Windows.FrameworkElement, IDisposable { private readonly Wpf.Ui.Tray.Internal.InternalNotifyIconManager internalNotifyIconManager; /// - /// Whether the control is disposed. + /// Gets or sets a value indicating whether the control is disposed. /// - protected bool Disposed = false; + protected bool Disposed { get; set; } = false; - #region Public variables - - /// - public int Id => this.internalNotifyIconManager.Id; + public int Id => internalNotifyIconManager.Id; /// - /// Whether the icon is registered in the tray menu. + /// Gets a value indicating whether the icon is registered in the tray menu. /// - public bool IsRegistered => this.internalNotifyIconManager.IsRegistered; + public bool IsRegistered => internalNotifyIconManager.IsRegistered; - /// public HwndSource? HookWindow { get; set; } - /// public IntPtr ParentHandle { get; set; } - #endregion - - #region Properties - - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty TooltipTextProperty = DependencyProperty.Register( nameof(TooltipText), typeof(string), typeof(NotifyIcon), - new PropertyMetadata(String.Empty, OnTooltipTextChanged) + new PropertyMetadata(string.Empty, OnTooltipTextChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty FocusOnLeftClickProperty = DependencyProperty.Register( nameof(FocusOnLeftClick), typeof(bool), @@ -79,9 +64,7 @@ public class NotifyIcon : System.Windows.FrameworkElement new PropertyMetadata(true, OnFocusOnLeftClickChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty MenuOnRightClickProperty = DependencyProperty.Register( nameof(MenuOnRightClick), typeof(bool), @@ -89,9 +72,7 @@ public class NotifyIcon : System.Windows.FrameworkElement new PropertyMetadata(true, OnMenuOnRightClickChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(ImageSource), @@ -99,9 +80,7 @@ public class NotifyIcon : System.Windows.FrameworkElement new PropertyMetadata((ImageSource)null!, OnIconChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty MenuProperty = DependencyProperty.Register( nameof(Menu), typeof(ContextMenu), @@ -109,9 +88,7 @@ public class NotifyIcon : System.Windows.FrameworkElement new PropertyMetadata(null, OnMenuChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty MenuFontSizeProperty = DependencyProperty.Register( nameof(MenuFontSize), typeof(double), @@ -119,7 +96,6 @@ public class NotifyIcon : System.Windows.FrameworkElement new PropertyMetadata(14d) ); - /// public string TooltipText { get => (string)GetValue(TooltipTextProperty); @@ -127,7 +103,7 @@ public string TooltipText } /// - /// Gets or sets the value indicating whether to show the on single right click. + /// Gets or sets a value indicating whether to show the on single right click. /// public bool MenuOnRightClick { @@ -136,7 +112,7 @@ public bool MenuOnRightClick } /// - /// Gets or sets the value indicating whether to focus the on single left click. + /// Gets or sets a value indicating whether to focus the on single left click. /// public bool FocusOnLeftClick { @@ -144,7 +120,6 @@ public bool FocusOnLeftClick set => SetValue(FocusOnLeftClickProperty, value); } - /// public ImageSource Icon { get => (ImageSource)GetValue(IconProperty); @@ -152,11 +127,11 @@ public ImageSource Icon } /// - /// Context menu. + /// Gets or sets the context menu. /// - public ContextMenu Menu + public ContextMenu? Menu { - get => (ContextMenu)GetValue(MenuProperty); + get => (ContextMenu?)GetValue(MenuProperty); set => SetValue(MenuProperty, value); } @@ -166,13 +141,7 @@ public double MenuFontSize set => SetValue(MenuFontSizeProperty, value); } - #endregion - - #region Events - - /// - /// Registration for . - /// + /// Identifies the routed event. public static readonly RoutedEvent LeftClickEvent = EventManager.RegisterRoutedEvent( nameof(LeftClick), RoutingStrategy.Bubble, @@ -180,9 +149,7 @@ public double MenuFontSize typeof(NotifyIcon) ); - /// - /// Registration for . - /// + /// Identifies the routed event. public static readonly RoutedEvent LeftDoubleClickEvent = EventManager.RegisterRoutedEvent( nameof(LeftDoubleClick), RoutingStrategy.Bubble, @@ -190,9 +157,7 @@ public double MenuFontSize typeof(NotifyIcon) ); - /// - /// Registration for . - /// + /// Identifies the routed event. public static readonly RoutedEvent RightClickEvent = EventManager.RegisterRoutedEvent( nameof(RightClick), RoutingStrategy.Bubble, @@ -200,9 +165,7 @@ public double MenuFontSize typeof(NotifyIcon) ); - /// - /// Registration for . - /// + /// Identifies the routed event. public static readonly RoutedEvent RightDoubleClickEvent = EventManager.RegisterRoutedEvent( nameof(RightDoubleClick), RoutingStrategy.Bubble, @@ -210,9 +173,7 @@ public double MenuFontSize typeof(NotifyIcon) ); - /// - /// Registration for . - /// + /// Identifies the routed event. public static readonly RoutedEvent MiddleClickEvent = EventManager.RegisterRoutedEvent( nameof(MiddleClick), RoutingStrategy.Bubble, @@ -220,9 +181,7 @@ public double MenuFontSize typeof(NotifyIcon) ); - /// - /// Registration for . - /// + /// Identifies the routed event. public static readonly RoutedEvent MiddleDoubleClickEvent = EventManager.RegisterRoutedEvent( nameof(MiddleDoubleClick), RoutingStrategy.Bubble, @@ -284,33 +243,28 @@ public event RoutedNotifyIconEvent MiddleDoubleClick remove => RemoveHandler(MiddleDoubleClickEvent, value); } - #endregion - - #region General methods - public NotifyIcon() { - this.internalNotifyIconManager = new Wpf.Ui.Tray.Internal.InternalNotifyIconManager(); + internalNotifyIconManager = new Wpf.Ui.Tray.Internal.InternalNotifyIconManager(); RegisterHandlers(); } /// - /// Control finalizer. + /// Finalizes an instance of the class. /// ~NotifyIcon() => Dispose(false); /// /// Tries to register the in the shell. /// - public void Register() => this.internalNotifyIconManager.Register(); + public void Register() => internalNotifyIconManager.Register(); /// /// Tries to unregister the from the shell. /// - public void Unregister() => this.internalNotifyIconManager.Unregister(); + public void Unregister() => internalNotifyIconManager.Unregister(); - /// public void Dispose() { Dispose(true); @@ -318,17 +272,15 @@ public void Dispose() GC.SuppressFinalize(this); } - #endregion - - #region Protected methods - /// protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); - if (this.internalNotifyIconManager.IsRegistered) + if (internalNotifyIconManager.IsRegistered) + { return; + } InitializeIcon(); @@ -400,32 +352,32 @@ protected virtual void OnMiddleDoubleClick() protected virtual void Dispose(bool disposing) { if (Disposed) + { return; + } Disposed = true; if (!disposing) + { return; + } -#if DEBUG System.Diagnostics.Debug.WriteLine($"INFO | {typeof(NotifyIcon)} disposed.", "Wpf.Ui.NotifyIcon"); -#endif Unregister(); - this.internalNotifyIconManager.Dispose(); + internalNotifyIconManager.Dispose(); } - #endregion - /// /// This virtual method is called when of is changed. /// /// New context menu object. protected virtual void OnMenuChanged(ContextMenu contextMenu) { - this.internalNotifyIconManager.ContextMenu = contextMenu; - this.internalNotifyIconManager.ContextMenu.FontSize = MenuFontSize; + internalNotifyIconManager.ContextMenu = contextMenu; + internalNotifyIconManager.ContextMenu.SetCurrentValue(Control.FontSizeProperty, MenuFontSize); } private static void OnTooltipTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) @@ -435,7 +387,7 @@ private static void OnTooltipTextChanged(DependencyObject d, DependencyPropertyC return; } - notifyIcon.TooltipText = e.NewValue as string ?? String.Empty; + notifyIcon.TooltipText = e.NewValue as string ?? string.Empty; } private static void OnIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) @@ -446,13 +398,15 @@ private static void OnIconChanged(DependencyObject d, DependencyPropertyChangedE } notifyIcon.internalNotifyIconManager.Icon = e.NewValue as ImageSource; - notifyIcon.internalNotifyIconManager.ModifyIcon(); + _ = notifyIcon.internalNotifyIconManager.ModifyIcon(); } private static void OnFocusOnLeftClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not NotifyIcon notifyIcon) + { return; + } if (e.NewValue is not bool newValue) { @@ -467,7 +421,9 @@ private static void OnFocusOnLeftClickChanged(DependencyObject d, DependencyProp private static void OnMenuOnRightClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not NotifyIcon notifyIcon) + { return; + } if (e.NewValue is not bool newValue) { @@ -482,29 +438,33 @@ private static void OnMenuOnRightClickChanged(DependencyObject d, DependencyProp private static void OnMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not NotifyIcon notifyIcon) + { return; + } if (e.NewValue is not ContextMenu contextMenu) + { return; + } notifyIcon.OnMenuChanged(contextMenu); } private void InitializeIcon() { - this.internalNotifyIconManager.TooltipText = TooltipText; - this.internalNotifyIconManager.Icon = Icon; - this.internalNotifyIconManager.MenuOnRightClick = MenuOnRightClick; - this.internalNotifyIconManager.FocusOnLeftClick = FocusOnLeftClick; + internalNotifyIconManager.TooltipText = TooltipText; + internalNotifyIconManager.Icon = Icon; + internalNotifyIconManager.MenuOnRightClick = MenuOnRightClick; + internalNotifyIconManager.FocusOnLeftClick = FocusOnLeftClick; } private void RegisterHandlers() { - this.internalNotifyIconManager.LeftClick += OnLeftClick; - this.internalNotifyIconManager.LeftDoubleClick += OnLeftDoubleClick; - this.internalNotifyIconManager.RightClick += OnRightClick; - this.internalNotifyIconManager.RightDoubleClick += OnRightDoubleClick; - this.internalNotifyIconManager.MiddleClick += OnMiddleClick; - this.internalNotifyIconManager.MiddleDoubleClick += OnMiddleDoubleClick; + internalNotifyIconManager.LeftClick += OnLeftClick; + internalNotifyIconManager.LeftDoubleClick += OnLeftDoubleClick; + internalNotifyIconManager.RightClick += OnRightClick; + internalNotifyIconManager.RightDoubleClick += OnRightDoubleClick; + internalNotifyIconManager.MiddleClick += OnMiddleClick; + internalNotifyIconManager.MiddleDoubleClick += OnMiddleDoubleClick; } } diff --git a/src/Wpf.Ui.Tray/Hicon.cs b/src/Wpf.Ui.Tray/Hicon.cs index c676177f0..f86466243 100644 --- a/src/Wpf.Ui.Tray/Hicon.cs +++ b/src/Wpf.Ui.Tray/Hicon.cs @@ -2,6 +2,9 @@ // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. +// +// TODO: This class is the only reason for using System.Drawing.Common. +// It is worth looking for a way to get hIcon without using it. using System; using System.Diagnostics; @@ -12,8 +15,6 @@ namespace Wpf.Ui.Tray; -// TODO: This class is the only reason for using System.Drawing.Common. It is worth looking for a way to get hIcon without using it. - /// /// Facilitates the creation of a hIcon. /// @@ -22,14 +23,13 @@ internal static class Hicon /// /// Tries to take the icon pointer assigned to the application. /// - /// public static IntPtr FromApp() { try { var processName = Process.GetCurrentProcess().MainModule?.FileName; - if (String.IsNullOrEmpty(processName)) + if (string.IsNullOrEmpty(processName)) { return IntPtr.Zero; } @@ -41,17 +41,17 @@ public static IntPtr FromApp() return IntPtr.Zero; } - //appIconsExtractIcon.ToBitmap(); + /*appIconsExtractIcon.ToBitmap();*/ return appIconsExtractIcon.Handle; } catch (Exception e) { -#if DEBUG System.Diagnostics.Debug.WriteLine( $"ERROR | Unable to get application hIcon - {e}", "Wpf.Ui.Hicon" ); +#if DEBUG throw; #else return IntPtr.Zero; @@ -65,19 +65,16 @@ public static IntPtr FromApp() /// Image source. public static IntPtr FromSource(ImageSource source) { - var hIcon = IntPtr.Zero; - var bitmapSource = source as BitmapSource; + IntPtr hIcon = IntPtr.Zero; var bitmapFrame = source as BitmapFrame; - if (bitmapSource == null) + if (source is not BitmapSource bitmapSource) { -#if DEBUG System.Diagnostics.Debug.WriteLine( $"ERROR | Unable to allocate hIcon, ImageSource is not a BitmapSource", "Wpf.Ui.Hicon" ); -#endif - return IntPtr.Zero; + return hIcon; } if ((bitmapFrame?.Decoder?.Frames?.Count ?? 0) > 1) @@ -96,14 +93,11 @@ public static IntPtr FromSource(ImageSource source) if (!gcHandle.IsAllocated) { -#if DEBUG System.Diagnostics.Debug.WriteLine( $"ERROR | Unable to allocate hIcon, allocation failed.", "Wpf.Ui.Hicon" ); -#endif - - return IntPtr.Zero; + return hIcon; } // Specifies that the format is 32 bits per pixel; 8 bits each are used for the alpha, red, green, and blue components. diff --git a/src/Wpf.Ui.Tray/INotifyIcon.cs b/src/Wpf.Ui.Tray/INotifyIcon.cs index d822713b6..13108eab4 100644 --- a/src/Wpf.Ui.Tray/INotifyIcon.cs +++ b/src/Wpf.Ui.Tray/INotifyIcon.cs @@ -17,17 +17,17 @@ namespace Wpf.Ui.Tray; internal interface INotifyIcon { /// - /// Notify icon shell data. + /// Gets or sets the notify icon shell data. /// public Interop.Shell32.NOTIFYICONDATA ShellIconData { get; set; } /// - /// Whether the icon is currently registered in the tray area. + /// Gets or sets a value indicating whether the icon is currently registered in the tray area. /// bool IsRegistered { get; set; } /// - /// Gets the Shell identifier of the icon. + /// Gets or sets the Shell identifier of the icon. /// int Id { get; set; } @@ -49,15 +49,15 @@ internal interface INotifyIcon /// /// Gets or sets the menu displayed when the icon is right-clicked. /// - ContextMenu ContextMenu { get; set; } + ContextMenu? ContextMenu { get; set; } /// - /// Gets or sets the value indicating whether to focus the on single left click. + /// Gets or sets a value indicating whether to focus the on single left click. /// bool FocusOnLeftClick { get; set; } /// - /// Gets or sets the value indicating whether to show the on single right click. + /// Gets or sets a value indicating whether to show the on single right click. /// bool MenuOnRightClick { get; set; } diff --git a/src/Wpf.Ui.Tray/INotifyIconService.cs b/src/Wpf.Ui.Tray/INotifyIconService.cs index 66a13e964..27cab614a 100644 --- a/src/Wpf.Ui.Tray/INotifyIconService.cs +++ b/src/Wpf.Ui.Tray/INotifyIconService.cs @@ -15,12 +15,12 @@ namespace Wpf.Ui.Tray; public interface INotifyIconService { /// - /// Whether the notify icon is registered in the tray. + /// Gets the notify icon id. /// public int Id { get; } /// - /// Whether the notify icon is registered in the tray. + /// Gets a value indicating whether the notify icon is registered in the tray. /// public bool IsRegistered { get; } @@ -30,14 +30,14 @@ public interface INotifyIconService public string TooltipText { get; set; } /// - /// Context menu displayed after clicking the icon. + /// Gets or sets the context menu displayed after clicking the icon. /// - ContextMenu ContextMenu { get; set; } + ContextMenu? ContextMenu { get; set; } /// /// Gets or sets the of the tray icon. /// - public ImageSource Icon { get; set; } + public ImageSource? Icon { get; set; } /// /// Tries to register the Notify Icon in the shell. diff --git a/src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs b/src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs index 8e00c0c2a..f3e0abe4d 100644 --- a/src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs +++ b/src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs @@ -30,7 +30,7 @@ internal class InternalNotifyIconManager : IDisposable, INotifyIcon public bool IsRegistered { get; set; } /// - public string TooltipText { get; set; } = String.Empty; + public string TooltipText { get; set; } = string.Empty; /// public ImageSource? Icon { get; set; } = default!; @@ -124,12 +124,10 @@ protected virtual void OnThemeChanged(ApplicationTheme currentApplicationTheme, /// protected virtual void FocusApp() { -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {typeof(TrayHandler)} invoked {nameof(FocusApp)} method.", "Wpf.Ui.NotifyIcon" ); -#endif Window mainWindow = Application.Current.MainWindow; if (mainWindow == null) @@ -155,7 +153,7 @@ protected virtual void FocusApp() mainWindow.Topmost = false; } - mainWindow.Focus(); + _ = mainWindow.Focus(); } /// @@ -163,12 +161,11 @@ protected virtual void FocusApp() /// protected virtual void OpenMenu() { -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {typeof(TrayHandler)} invoked {nameof(OpenMenu)} method.", "Wpf.Ui.NotifyIcon" ); -#endif + if (ContextMenu is null) { return; @@ -252,12 +249,10 @@ protected virtual void Dispose(bool disposing) return; } -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {typeof(NotifyIconService)} disposed.", "Wpf.Ui.NotifyIcon" ); -#endif Unregister(); } @@ -270,12 +265,10 @@ public IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bo switch (uMsg) { case Interop.User32.WM.DESTROY: -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {typeof(TrayHandler)} received {uMsg} message.", "Wpf.Ui.NotifyIcon" ); -#endif Dispose(); handled = true; @@ -283,23 +276,19 @@ public IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bo return IntPtr.Zero; case Interop.User32.WM.NCDESTROY: -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {typeof(TrayHandler)} received {uMsg} message.", "Wpf.Ui.NotifyIcon" ); -#endif handled = false; return IntPtr.Zero; case Interop.User32.WM.CLOSE: -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {typeof(TrayHandler)} received {uMsg} message.", "Wpf.Ui.NotifyIcon" ); -#endif handled = true; return IntPtr.Zero; diff --git a/src/Wpf.Ui.Tray/Interop/Shell32.cs b/src/Wpf.Ui.Tray/Interop/Shell32.cs index ebcd71a7a..65052b8e8 100644 --- a/src/Wpf.Ui.Tray/Interop/Shell32.cs +++ b/src/Wpf.Ui.Tray/Interop/Shell32.cs @@ -9,11 +9,14 @@ namespace Wpf.Ui.Tray.Interop; +// ReSharper disable IdentifierTypo +// ReSharper disable InconsistentNaming +#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter +#pragma warning disable SA1401 // Fields should be private + /// /// The Windows UI provides users with access to a wide variety of objects necessary to run applications and manage the operating system. /// -// ReSharper disable IdentifierTypo -// ReSharper disable InconsistentNaming internal static class Shell32 { /// @@ -105,7 +108,7 @@ public class NOTIFYICONDATA /// 0x00000004. The szTip member is valid. /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x80)] // 128 - public string szTip; + public string? szTip; /// /// The state of the icon. There are two flags that can be set independently. @@ -117,7 +120,7 @@ public class NOTIFYICONDATA public uint dwStateMask; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x100)] // 256 - public string szInfo; + public string? szInfo; /// /// Prior to Vista this was a union of uTimeout and uVersion. As of Vista, uTimeout has been deprecated. @@ -125,14 +128,14 @@ public class NOTIFYICONDATA public uint uVersion; // Used with Shell_NotifyIcon flag NIM_SETVERSION. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x40)] // 64 - public string szInfoTitle; + public string? szInfoTitle; public uint dwInfoFlags; public Guid guidItem; // Vista only - IntPtr hBalloonIcon; + public IntPtr hBalloonIcon; } [DllImport(Libraries.Shell32, PreserveSig = false)] @@ -158,7 +161,7 @@ public static extern int SHCreateItemFromParsingName( /// /// Sets the User Model AppID for the current process, enabling Windows to retrieve this ID /// - /// + /// The string ID to be assigned [DllImport(Libraries.Shell32, PreserveSig = false)] public static extern void SetCurrentProcessExplicitAppUserModelID( [MarshalAs(UnmanagedType.LPWStr)] string AppID @@ -167,9 +170,13 @@ public static extern void SetCurrentProcessExplicitAppUserModelID( /// /// Retrieves the User Model AppID that has been explicitly set for the current process via SetCurrentProcessExplicitAppUserModelID /// - /// + /// Out parameter that receives the string ID. + /// An HRESULT indicating success (S_OK) or failure of the operation. If the function fails, the returned AppID is null. [DllImport(Libraries.Shell32)] public static extern int GetCurrentProcessExplicitAppUserModelID( [Out, MarshalAs(UnmanagedType.LPWStr)] out string AppID ); } + +#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter +#pragma warning restore SA1401 // Fields should be private diff --git a/src/Wpf.Ui.Tray/Interop/User32.cs b/src/Wpf.Ui.Tray/Interop/User32.cs index 86397e655..26e6829a5 100644 --- a/src/Wpf.Ui.Tray/Interop/User32.cs +++ b/src/Wpf.Ui.Tray/Interop/User32.cs @@ -10,14 +10,14 @@ namespace Wpf.Ui.Tray.Interop; -/// -/// USER procedure declarations, constant definitions and macros. -/// // ReSharper disable IdentifierTypo // ReSharper disable InconsistentNaming #pragma warning disable SA1300 // Element should begin with upper-case letter #pragma warning disable SA1307 // Accessible fields should begin with upper-case letter -#pragma warning disable SA1401 // Fields should be private + +/// +/// USER procedure declarations, constant definitions and macros. +/// internal static class User32 { /// @@ -29,14 +29,14 @@ public enum SWP ASYNCWINDOWPOS = 0x4000, DEFERERASE = 0x2000, DRAWFRAME = 0x0020, - FRAMECHANGED = 0x0020, + FRAMECHANGED = DRAWFRAME, HIDEWINDOW = 0x0080, NOACTIVATE = 0x0010, NOCOPYBITS = 0x0100, NOMOVE = 0x0002, NOOWNERZORDER = 0x0200, NOREDRAW = 0x0008, - NOREPOSITION = 0x0200, + NOREPOSITION = NOOWNERZORDER, NOSENDCHANGING = 0x0400, NOSIZE = 0x0001, NOZORDER = 0x0004, @@ -54,7 +54,7 @@ public enum MF : uint /// DOES_NOT_EXIST = unchecked((uint)-1), ENABLED = 0, - BYCOMMAND = 0, + BYCOMMAND = ENABLED, GRAYED = 1, DISABLED = 2, } @@ -430,7 +430,7 @@ public enum WM SHOWWINDOW = 0x0018, CTLCOLOR = 0x0019, WININICHANGE = 0x001A, - SETTINGCHANGE = 0x001A, + SETTINGCHANGE = WININICHANGE, ACTIVATEAPP = 0x001C, SETCURSOR = 0x0020, MOUSEACTIVATE = 0x0021, @@ -511,7 +511,7 @@ public enum WM TABLET_DEFBASE = 0x02C0, - //WM_TABLET_MAXOFFSET = 0x20, + /*WM_TABLET_MAXOFFSET = 0x20,*/ TABLET_ADDED = TABLET_DEFBASE + 8, TABLET_DELETED = TABLET_DEFBASE + 9, @@ -549,20 +549,17 @@ public enum WM GETTITLEBARINFOEX = 0x033F, - #region Windows 7 - + // Windows 7 DWMSENDICONICTHUMBNAIL = 0x0323, DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326, - #endregion - USER = 0x0400, /// /// This is the hard-coded message value used by WinForms for Shell_NotifyIcon. /// It's relatively safe to reuse. /// - TRAYMOUSEMESSAGE = 0x800, //WM_USER + 1024 + TRAYMOUSEMESSAGE = 0x800, // WM_USER + 1024 APP = 0x8000, } @@ -590,16 +587,16 @@ public enum WS : long GROUP = 0x00020000, TABSTOP = 0x00010000, - MINIMIZEBOX = 0x00020000, - MAXIMIZEBOX = 0x00010000, + MINIMIZEBOX = GROUP, + MAXIMIZEBOX = TABSTOP, CAPTION = BORDER | DLGFRAME, TILED = OVERLAPPED, ICONIC = MINIMIZE, SIZEBOX = THICKFRAME, + OVERLAPPEDWINDOW = OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX, TILEDWINDOW = OVERLAPPEDWINDOW, - OVERLAPPEDWINDOW = OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX, POPUPWINDOW = POPUP | BORDER | SYSMENU, CHILDWINDOW = CHILD, } @@ -622,11 +619,11 @@ public enum WS_EX : long CLIENTEDGE = 0x00000200, CONTEXTHELP = 0x00000400, RIGHT = 0x00001000, - LEFT = 0x00000000, + LEFT = NONE, RTLREADING = 0x00002000, - LTRREADING = 0x00000000, + LTRREADING = NONE, LEFTSCROLLBAR = 0x00004000, - RIGHTSCROLLBAR = 0x00000000, + RIGHTSCROLLBAR = NONE, CONTROLPARENT = 0x00010000, STATICEDGE = 0x00020000, APPWINDOW = 0x00040000, @@ -738,10 +735,10 @@ public enum SW { HIDE = 0, SHOWNORMAL = 1, - NORMAL = 1, + NORMAL = SHOWNORMAL, SHOWMINIMIZED = 2, SHOWMAXIMIZED = 3, - MAXIMIZE = 3, + MAXIMIZE = SHOWMAXIMIZED, SHOWNOACTIVATE = 4, SHOW = 5, MINIMIZE = 6, @@ -899,7 +896,7 @@ public static extern bool ChangeWindowMessageFilterEx( /// A handle to the window whose window procedure is to receive the message. /// The message to be posted. /// Additional message-specific information. - /// Additional message-specific information. + /// Additional message-specific information.~ /// If the function succeeds, the return value is nonzero. [DllImport(Libraries.User32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -917,7 +914,7 @@ [In] IntPtr lParam /// A handle to the window whose window procedure is to receive the message. /// The message to be posted. /// Additional message-specific information. - /// Additional message-specific information. + /// Additional message-specific information.~ /// If the function succeeds, the return value is nonzero. [DllImport(Libraries.User32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -934,7 +931,7 @@ [In] IntPtr lParam /// A handle to the window whose window procedure is to receive the message. /// The message to be posted. /// Additional message-specific information. - /// Additional message-specific information. + /// Additional message-specific information.~ /// If the function succeeds, the return value is nonzero. [DllImport(Libraries.User32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -951,7 +948,7 @@ [In] IntPtr lParam /// A handle to the window whose window procedure will receive the message. /// The message to be sent. /// Additional message-specific information. - /// Additional message-specific information. + /// Additional message-specific information.~ /// The return value specifies the result of the message processing; it depends on the message sent. [DllImport(Libraries.User32, CharSet = CharSet.Auto)] public static extern int SendMessage( @@ -1028,7 +1025,7 @@ public static IntPtr CreateWindowEx( [In, Optional] IntPtr lpParam ) { - var ret = CreateWindowExW( + IntPtr ret = CreateWindowExW( dwExStyle, lpClassName, lpWindowName, @@ -1086,7 +1083,7 @@ public static IntPtr CreateWindowEx( /// A handle to the window procedure that received the message. /// The message. /// Additional message information. The content of this parameter depends on the value of the Msg parameter. - /// Additional message information. The content of this parameter depends on the value of the Msg parameter. + /// Additional message information. The content of this parameter depends on the value of the Msg parameter.~ /// The return value is the result of the message processing and depends on the message. [DllImport(Libraries.User32, CharSet = CharSet.Unicode)] public static extern IntPtr DefWindowProcW( @@ -1104,7 +1101,7 @@ [In] IntPtr lParam /// A handle to the window procedure that received the message. /// The message. /// Additional message information. The content of this parameter depends on the value of the Msg parameter. - /// Additional message information. The content of this parameter depends on the value of the Msg parameter. + /// Additional message information. The content of this parameter depends on the value of the Msg parameter.~ /// The return value is the result of the message processing and depends on the message. [DllImport(Libraries.User32, CharSet = CharSet.Auto)] public static extern IntPtr DefWindowProcA( @@ -1121,7 +1118,7 @@ [In] IntPtr lParam /// A handle to the window procedure that received the message. /// The message. /// Additional message information. The content of this parameter depends on the value of the Msg parameter. - /// Additional message information. The content of this parameter depends on the value of the Msg parameter. + /// Additional message information. The content of this parameter depends on the value of the Msg parameter.~ /// The return value is the result of the message processing and depends on the message. [DllImport(Libraries.User32, CharSet = CharSet.Auto)] public static extern IntPtr DefWindowProc( @@ -1134,7 +1131,7 @@ [In] IntPtr lParam /// /// Retrieves information about the specified window. The function also retrieves the 32-bit (DWORD) value at the specified offset into the extra window memory. /// If you are retrieving a pointer or a handle, this function has been superseded by the function. - /// Unicode declaration for + /// Unicode declaration for /// /// A handle to the window and, indirectly, the class to which the window belongs. /// The zero-based offset to the value to be retrieved. @@ -1145,7 +1142,7 @@ [In] IntPtr lParam /// /// Retrieves information about the specified window. The function also retrieves the 32-bit (DWORD) value at the specified offset into the extra window memory. /// If you are retrieving a pointer or a handle, this function has been superseded by the function. - /// ANSI declaration for + /// ANSI declaration for /// /// A handle to the window and, indirectly, the class to which the window belongs. /// The zero-based offset to the value to be retrieved. @@ -1549,6 +1546,6 @@ public static extern int GetWindowCompositionAttribute( [DllImport(Libraries.User32, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)] public static extern uint GetDpiForWindow([In] HandleRef hwnd); } + #pragma warning restore SA1300 // Element should begin with upper-case letter #pragma warning restore SA1307 // Accessible fields should begin with upper-case letter -#pragma warning restore SA1401 // Fields should be private diff --git a/src/Wpf.Ui.Tray/NotifyIconEvent.cs b/src/Wpf.Ui.Tray/NotifyIconEventHandler.cs similarity index 100% rename from src/Wpf.Ui.Tray/NotifyIconEvent.cs rename to src/Wpf.Ui.Tray/NotifyIconEventHandler.cs diff --git a/src/Wpf.Ui.Tray/NotifyIconService.cs b/src/Wpf.Ui.Tray/NotifyIconService.cs index c4efcf659..6b5ea4931 100644 --- a/src/Wpf.Ui.Tray/NotifyIconService.cs +++ b/src/Wpf.Ui.Tray/NotifyIconService.cs @@ -19,31 +19,31 @@ public class NotifyIconService : INotifyIconService public Window ParentWindow { get; internal set; } = null!; - public int Id => this.internalNotifyIconManager.Id; + public int Id => internalNotifyIconManager.Id; - public bool IsRegistered => this.internalNotifyIconManager.IsRegistered; + public bool IsRegistered => internalNotifyIconManager.IsRegistered; public string TooltipText { - get => this.internalNotifyIconManager.TooltipText; - set => this.internalNotifyIconManager.TooltipText = value; + get => internalNotifyIconManager.TooltipText; + set => internalNotifyIconManager.TooltipText = value; } - public ContextMenu ContextMenu + public ContextMenu? ContextMenu { - get => this.internalNotifyIconManager.ContextMenu; - set => this.internalNotifyIconManager.ContextMenu = value; + get => internalNotifyIconManager.ContextMenu; + set => internalNotifyIconManager.ContextMenu = value; } - public ImageSource Icon + public ImageSource? Icon { - get => this.internalNotifyIconManager.Icon; - set => this.internalNotifyIconManager.Icon = value; + get => internalNotifyIconManager.Icon; + set => internalNotifyIconManager.Icon = value; } public NotifyIconService() { - this.internalNotifyIconManager = new Internal.InternalNotifyIconManager(); + internalNotifyIconManager = new Internal.InternalNotifyIconManager(); RegisterHandlers(); } @@ -52,15 +52,15 @@ public bool Register() { if (ParentWindow is not null) { - return this.internalNotifyIconManager.Register(ParentWindow); + return internalNotifyIconManager.Register(ParentWindow); } - return this.internalNotifyIconManager.Register(); + return internalNotifyIconManager.Register(); } public bool Unregister() { - return this.internalNotifyIconManager.Unregister(); + return internalNotifyIconManager.Unregister(); } /// @@ -105,18 +105,18 @@ protected virtual void OnMiddleClick() { } /// protected virtual void OnMiddleDoubleClick() { } - private void OnParentWindowClosing(object sender, CancelEventArgs e) + private void OnParentWindowClosing(object? sender, CancelEventArgs e) { - this.internalNotifyIconManager.Dispose(); + internalNotifyIconManager.Dispose(); } private void RegisterHandlers() { - this.internalNotifyIconManager.LeftClick += OnLeftClick; - this.internalNotifyIconManager.LeftDoubleClick += OnLeftDoubleClick; - this.internalNotifyIconManager.RightClick += OnRightClick; - this.internalNotifyIconManager.RightDoubleClick += OnRightDoubleClick; - this.internalNotifyIconManager.MiddleClick += OnMiddleClick; - this.internalNotifyIconManager.MiddleDoubleClick += OnMiddleDoubleClick; + internalNotifyIconManager.LeftClick += OnLeftClick; + internalNotifyIconManager.LeftDoubleClick += OnLeftDoubleClick; + internalNotifyIconManager.RightClick += OnRightClick; + internalNotifyIconManager.RightDoubleClick += OnRightDoubleClick; + internalNotifyIconManager.MiddleClick += OnMiddleClick; + internalNotifyIconManager.MiddleDoubleClick += OnMiddleDoubleClick; } } diff --git a/src/Wpf.Ui.Tray/RoutedNotifyIconEvent.cs b/src/Wpf.Ui.Tray/RoutedNotifyIconEvent.cs index 399fa70fd..7edbdc1eb 100644 --- a/src/Wpf.Ui.Tray/RoutedNotifyIconEvent.cs +++ b/src/Wpf.Ui.Tray/RoutedNotifyIconEvent.cs @@ -12,7 +12,8 @@ namespace Wpf.Ui.Tray; /// /// Event triggered on successful navigation. /// -/// Current navigation instance. +/// Source of the event, which should be the current navigation instance. +/// Event data containing information about the navigation event. #if NET5_0_OR_GREATER public delegate void RoutedNotifyIconEvent([NotNull] NotifyIcon sender, RoutedEventArgs e); #else diff --git a/src/Wpf.Ui.Tray/TrayData.cs b/src/Wpf.Ui.Tray/TrayData.cs index 791a5e84e..a701b5f8c 100644 --- a/src/Wpf.Ui.Tray/TrayData.cs +++ b/src/Wpf.Ui.Tray/TrayData.cs @@ -13,7 +13,7 @@ namespace Wpf.Ui.Tray; internal static class TrayData { /// - /// Collection of registered tray icons. + /// Gets or sets the collection of registered tray icons. /// public static List NotifyIcons { get; set; } = new(); } diff --git a/src/Wpf.Ui.Tray/TrayHandler.cs b/src/Wpf.Ui.Tray/TrayHandler.cs index 1fcb0ef2e..1648868cf 100644 --- a/src/Wpf.Ui.Tray/TrayHandler.cs +++ b/src/Wpf.Ui.Tray/TrayHandler.cs @@ -14,23 +14,21 @@ namespace Wpf.Ui.Tray; internal class TrayHandler : HwndSource { /// - /// Id of the hooked element. + /// Gets or sets the id of the hooked element. /// public int ElementId { get; internal set; } /// - /// Creates a new hWnd as a child with transparency parameters, no size and in the default position. Then, it attach the default delegation to the messages it receives. + /// Initializes a new instance of the class, creating a new hWnd as a child with transparency parameters, no size, and in the default position. It attaches the default delegation to the messages it receives. /// /// The name of the created window. /// Parent of the created window. public TrayHandler(string name, IntPtr parent) : base(0x0, 0x4000000, 0x80000 | 0x20 | 0x00000008 | 0x08000000, 0, 0, 0, 0, name, parent) { -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | New {typeof(TrayHandler)} registered with handle: #{Handle}, and parent: #{parent}", "Wpf.Ui.TrayHandler" ); -#endif } } diff --git a/src/Wpf.Ui.Tray/TrayManager.cs b/src/Wpf.Ui.Tray/TrayManager.cs index fea87fe21..5635947bc 100644 --- a/src/Wpf.Ui.Tray/TrayManager.cs +++ b/src/Wpf.Ui.Tray/TrayManager.cs @@ -32,6 +32,11 @@ internal static class TrayManager { public static bool Register(INotifyIcon notifyIcon) { + if (notifyIcon is null) + { + return false; + } + return Register(notifyIcon, GetParentSource()); } @@ -45,7 +50,7 @@ public static bool Register(INotifyIcon notifyIcon, Window parentWindow) return Register(notifyIcon, (HwndSource)PresentationSource.FromVisual(parentWindow)); } - public static bool Register(INotifyIcon notifyIcon, HwndSource parentSource) + public static bool Register(INotifyIcon notifyIcon, HwndSource? parentSource) { if (parentSource is null) { @@ -54,7 +59,7 @@ public static bool Register(INotifyIcon notifyIcon, HwndSource parentSource) return false; } - Unregister(notifyIcon); + _ = Unregister(notifyIcon); return false; } @@ -66,7 +71,7 @@ public static bool Register(INotifyIcon notifyIcon, HwndSource parentSource) if (notifyIcon.IsRegistered) { - Unregister(notifyIcon); + _ = Unregister(notifyIcon); } notifyIcon.Id = TrayData.NotifyIcons.Count + 1; @@ -88,7 +93,7 @@ public static bool Register(INotifyIcon notifyIcon, HwndSource parentSource) dwState = 0x2 }; - if (!String.IsNullOrEmpty(notifyIcon.TooltipText)) + if (!string.IsNullOrEmpty(notifyIcon.TooltipText)) { notifyIcon.ShellIconData.szTip = notifyIcon.TooltipText; notifyIcon.ShellIconData.uFlags |= Interop.Shell32.NIF.TIP; @@ -98,7 +103,7 @@ public static bool Register(INotifyIcon notifyIcon, HwndSource parentSource) notifyIcon.HookWindow.AddHook(notifyIcon.WndProc); - Interop.Shell32.Shell_NotifyIcon(Interop.Shell32.NIM.ADD, notifyIcon.ShellIconData); + _ = Interop.Shell32.Shell_NotifyIcon(Interop.Shell32.NIM.ADD, notifyIcon.ShellIconData); TrayData.NotifyIcons.Add(notifyIcon); @@ -129,7 +134,7 @@ public static bool Unregister(INotifyIcon notifyIcon) return false; } - Interop.Shell32.Shell_NotifyIcon(Interop.Shell32.NIM.DELETE, notifyIcon.ShellIconData); + _ = Interop.Shell32.Shell_NotifyIcon(Interop.Shell32.NIM.DELETE, notifyIcon.ShellIconData); notifyIcon.IsRegistered = false; @@ -139,7 +144,7 @@ public static bool Unregister(INotifyIcon notifyIcon) /// /// Gets application source. /// - private static HwndSource GetParentSource() + private static HwndSource? GetParentSource() { Window mainWindow = Application.Current.MainWindow; @@ -153,7 +158,7 @@ private static HwndSource GetParentSource() private static void ReloadHicon(INotifyIcon notifyIcon) { - var hIcon = IntPtr.Zero; + IntPtr hIcon = IntPtr.Zero; if (notifyIcon.Icon is not null) { diff --git a/src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj b/src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj index ac77b6eb5..c506b47f4 100644 --- a/src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj +++ b/src/Wpf.Ui.Tray/Wpf.Ui.Tray.csproj @@ -66,6 +66,7 @@ true true false + True diff --git a/src/Wpf.Ui/Animations/TransitionAnimationProvider.cs b/src/Wpf.Ui/Animations/TransitionAnimationProvider.cs index abbcfe58c..652081570 100644 --- a/src/Wpf.Ui/Animations/TransitionAnimationProvider.cs +++ b/src/Wpf.Ui/Animations/TransitionAnimationProvider.cs @@ -27,33 +27,17 @@ public static class TransitionAnimationProvider /// Selected transition type. /// Transition duration. /// Returns if the transition was applied. Otherwise . - public static bool ApplyTransition(object element, Transition type, int duration) + public static bool ApplyTransition(object? element, Transition type, int duration) { - if (type == Transition.None) + if (type == Transition.None + || !HardwareAcceleration.IsSupported(RenderingTier.PartialAcceleration) + || element is not UIElement uiElement + || duration < 10) { return false; } - // Disable transitions for non-accelerated devices. - if (!HardwareAcceleration.IsSupported(RenderingTier.PartialAcceleration)) - { - return false; - } - - if (element is not UIElement uiElement) - { - return false; - } - - if (duration < 10) - { - return false; - } - - if (duration > 10000) - { - duration = 10000; - } + duration = duration > 10000 ? 10000 : duration; var timespanDuration = new Duration(TimeSpan.FromMilliseconds(duration)); diff --git a/src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs b/src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs index c969068a2..141e918d5 100644 --- a/src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs +++ b/src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs @@ -208,7 +208,6 @@ private static void UpdateColorResources( Color tertiaryAccent ) { -#if DEBUG System.Diagnostics.Debug.WriteLine("INFO | SystemAccentColor: " + systemAccent, "Wpf.Ui.Accent"); System.Diagnostics.Debug.WriteLine( "INFO | SystemAccentColorPrimary: " + primaryAccent, @@ -222,13 +221,10 @@ Color tertiaryAccent "INFO | SystemAccentColorTertiary: " + tertiaryAccent, "Wpf.Ui.Accent" ); -#endif if (secondaryAccent.GetBrightness() > BackgroundBrightnessThresholdValue) { -#if DEBUG System.Diagnostics.Debug.WriteLine("INFO | Text on accent is DARK", "Wpf.Ui.Accent"); -#endif UiApplication.Current.Resources["TextOnAccentFillColorPrimary"] = Color.FromArgb( 0xFF, 0x00, @@ -262,9 +258,7 @@ Color tertiaryAccent } else { -#if DEBUG System.Diagnostics.Debug.WriteLine("INFO | Text on accent is LIGHT", "Wpf.Ui.Accent"); -#endif UiApplication.Current.Resources["TextOnAccentFillColorPrimary"] = Color.FromArgb( 0xFF, 0xFF, diff --git a/src/Wpf.Ui/Appearance/ApplicationThemeManager.cs b/src/Wpf.Ui/Appearance/ApplicationThemeManager.cs index 539c5210d..f0d3ec7db 100644 --- a/src/Wpf.Ui/Appearance/ApplicationThemeManager.cs +++ b/src/Wpf.Ui/Appearance/ApplicationThemeManager.cs @@ -62,12 +62,10 @@ public static class ApplicationThemeManager /// Theme to set. /// Whether the custom background effect should be applied. /// Whether the color accents should be changed. - /// If , bypasses the app's theme compatibility check and tries to force the change of a background effect. public static void Apply( ApplicationTheme applicationTheme, WindowBackdropType backgroundEffect = WindowBackdropType.Mica, - bool updateAccent = true, - bool forceBackground = false + bool updateAccent = true ) { if (updateAccent) @@ -94,23 +92,14 @@ public static void Apply( themeDictionaryName = "Dark"; break; case ApplicationTheme.HighContrast: - switch (ApplicationThemeManager.GetSystemTheme()) + themeDictionaryName = ApplicationThemeManager.GetSystemTheme() switch { - case SystemTheme.HC1: - themeDictionaryName = "HC1"; - break; - case SystemTheme.HC2: - themeDictionaryName = "HC2"; - break; - case SystemTheme.HCBlack: - themeDictionaryName = "HCBlack"; - break; - case SystemTheme.HCWhite: - default: - themeDictionaryName = "HCWhite"; - break; - } - + SystemTheme.HC1 => "HC1", + SystemTheme.HC2 => "HC2", + SystemTheme.HCBlack => "HCBlack", + SystemTheme.HCWhite => "HCBlack", + _ => "HCWhite", + }; break; } @@ -119,12 +108,11 @@ public static void Apply( new Uri(ThemesDictionaryPath + themeDictionaryName + ".xaml", UriKind.Absolute) ); -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {typeof(ApplicationThemeManager)} tries to update theme to {themeDictionaryName} ({applicationTheme}): {isUpdated}", nameof(ApplicationThemeManager) ); -#endif + if (!isUpdated) { return; @@ -141,8 +129,7 @@ public static void Apply( WindowBackgroundManager.UpdateBackground( mainWindow, applicationTheme, - backgroundEffect, - forceBackground + backgroundEffect ); } } diff --git a/src/Wpf.Ui/Appearance/ObservedWindow.cs b/src/Wpf.Ui/Appearance/ObservedWindow.cs index 2febc935f..70023cb4a 100644 --- a/src/Wpf.Ui/Appearance/ObservedWindow.cs +++ b/src/Wpf.Ui/Appearance/ObservedWindow.cs @@ -14,13 +14,11 @@ internal class ObservedWindow public ObservedWindow( IntPtr handle, WindowBackdropType backdrop, - bool forceBackgroundReplace, bool updateAccents ) { Handle = handle; Backdrop = backdrop; - ForceBackgroundReplace = forceBackgroundReplace; UpdateAccents = updateAccents; HasHook = false; @@ -35,8 +33,6 @@ bool updateAccents public WindowBackdropType Backdrop { get; } - public bool ForceBackgroundReplace { get; } - public bool UpdateAccents { get; } public bool HasHook { get; private set; } diff --git a/src/Wpf.Ui/Appearance/SystemThemeManager.cs b/src/Wpf.Ui/Appearance/SystemThemeManager.cs index 4b48e1899..f14f33f33 100644 --- a/src/Wpf.Ui/Appearance/SystemThemeManager.cs +++ b/src/Wpf.Ui/Appearance/SystemThemeManager.cs @@ -65,9 +65,9 @@ private static SystemTheme GetCurrentSystemTheme() "CurrentTheme", "aero.theme" ) as string - ?? String.Empty; + ?? string.Empty; - if (!String.IsNullOrEmpty(currentTheme)) + if (!string.IsNullOrEmpty(currentTheme)) { currentTheme = currentTheme.ToLower().Trim(); @@ -128,8 +128,8 @@ private static SystemTheme GetCurrentSystemTheme() } } - //if (currentTheme.Contains("custom.theme")) - // return ; custom can be light or dark + /*if (currentTheme.Contains("custom.theme")) + return ; custom can be light or dark*/ var rawAppsUseLightTheme = Registry.GetValue( "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", "AppsUseLightTheme", diff --git a/src/Wpf.Ui/Appearance/SystemThemeWatcher.cs b/src/Wpf.Ui/Appearance/SystemThemeWatcher.cs index e68808789..415af2aae 100644 --- a/src/Wpf.Ui/Appearance/SystemThemeWatcher.cs +++ b/src/Wpf.Ui/Appearance/SystemThemeWatcher.cs @@ -25,7 +25,7 @@ namespace Wpf.Ui.Appearance; /// public static class SystemThemeWatcher { - private static readonly ICollection _observedWindows = new List(); + private static readonly List _observedWindows = []; /// /// Watches the and applies the background effect and theme according to the system theme. @@ -33,12 +33,10 @@ public static class SystemThemeWatcher /// The window that will be updated. /// Background effect to be applied when changing the theme. /// If , the accents will be updated when the change is detected. - /// If , bypasses the app's theme compatibility check and tries to force the change of a background effect. public static void Watch( Window? window, WindowBackdropType backdrop = WindowBackdropType.Mica, - bool updateAccents = true, - bool forceBackgroundReplace = false + bool updateAccents = true ) { if (window is null) @@ -48,21 +46,19 @@ public static void Watch( if (window.IsLoaded) { - ObserveLoadedWindow(window, backdrop, updateAccents, forceBackgroundReplace); + ObserveLoadedWindow(window, backdrop, updateAccents); } else { - ObserveWindowWhenLoaded(window, backdrop, updateAccents, forceBackgroundReplace); + ObserveWindowWhenLoaded(window, backdrop, updateAccents); } - if (!_observedWindows.Any()) + if (_observedWindows.Count == 0) { -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {typeof(SystemThemeWatcher)} changed the app theme on initialization.", nameof(SystemThemeWatcher) ); -#endif ApplicationThemeManager.ApplySystemTheme(updateAccents); } } @@ -70,8 +66,7 @@ public static void Watch( private static void ObserveLoadedWindow( Window window, WindowBackdropType backdrop, - bool updateAccents, - bool forceBackgroundReplace + bool updateAccents ) { IntPtr hWnd = @@ -84,14 +79,13 @@ bool forceBackgroundReplace throw new InvalidOperationException("Window handle cannot be empty"); } - ObserveLoadedHandle(new ObservedWindow(hWnd, backdrop, forceBackgroundReplace, updateAccents)); + ObserveLoadedHandle(new ObservedWindow(hWnd, backdrop, updateAccents)); } private static void ObserveWindowWhenLoaded( Window window, WindowBackdropType backdrop, - bool updateAccents, - bool forceBackgroundReplace + bool updateAccents ) { window.Loaded += (_, _) => @@ -106,7 +100,7 @@ bool forceBackgroundReplace throw new InvalidOperationException("Window handle cannot be empty"); } - ObserveLoadedHandle(new ObservedWindow(hWnd, backdrop, forceBackgroundReplace, updateAccents)); + ObserveLoadedHandle(new ObservedWindow(hWnd, backdrop, updateAccents)); }; } @@ -114,12 +108,10 @@ private static void ObserveLoadedHandle(ObservedWindow observedWindow) { if (!observedWindow.HasHook) { -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {observedWindow.Handle} ({observedWindow.RootVisual?.Title}) registered as watched window.", nameof(SystemThemeWatcher) ); -#endif observedWindow.AddHook(WndProc); _observedWindows.Add(observedWindow); } @@ -187,20 +179,17 @@ private static void UpdateObservedWindow(nint hWnd) ApplicationThemeManager.ApplySystemTheme(observedWindow.UpdateAccents); ApplicationTheme currentApplicationTheme = ApplicationThemeManager.GetAppTheme(); -#if DEBUG System.Diagnostics.Debug.WriteLine( $"INFO | {observedWindow.Handle} ({observedWindow.RootVisual?.Title}) triggered the application theme change to {ApplicationThemeManager.GetSystemTheme()}.", nameof(SystemThemeWatcher) ); -#endif if (observedWindow.RootVisual is not null) { WindowBackgroundManager.UpdateBackground( observedWindow.RootVisual, currentApplicationTheme, - observedWindow.Backdrop, - observedWindow.ForceBackgroundReplace + observedWindow.Backdrop ); } } diff --git a/src/Wpf.Ui/Appearance/WindowBackgroundManager.cs b/src/Wpf.Ui/Appearance/WindowBackgroundManager.cs index 5b573f818..2a1cf8e42 100644 --- a/src/Wpf.Ui/Appearance/WindowBackgroundManager.cs +++ b/src/Wpf.Ui/Appearance/WindowBackgroundManager.cs @@ -16,8 +16,7 @@ namespace Wpf.Ui.Appearance; /// WindowBackgroundManager.UpdateBackground( /// observedWindow.RootVisual, /// currentApplicationTheme, -/// observedWindow.Backdrop, -/// observedWindow.ForceBackgroundReplace +/// observedWindow.Backdrop /// ); /// /// @@ -59,14 +58,19 @@ public static void RemoveDarkThemeFromWindow(Window? window) window.Loaded += (sender, _) => UnsafeNativeMethods.RemoveWindowDarkMode(sender as Window); } + [Obsolete("Use UpdateBackground(Window, ApplicationTheme, WindowBackdropType) instead.")] + public static void UpdateBackground(Window? window, ApplicationTheme applicationTheme, WindowBackdropType backdrop, bool forceBackground) + { + UpdateBackground(window, applicationTheme, backdrop); + } + /// /// Forces change to application background. Required if custom background effect was previously applied. /// public static void UpdateBackground( Window? window, ApplicationTheme applicationTheme, - WindowBackdropType backdrop, - bool forceBackground + WindowBackdropType backdrop ) { if (window is null) diff --git a/src/Wpf.Ui/AutomationPeers/CardControlAutomationPeer.cs b/src/Wpf.Ui/AutomationPeers/CardControlAutomationPeer.cs index a4f6dc739..318478cf8 100644 --- a/src/Wpf.Ui/AutomationPeers/CardControlAutomationPeer.cs +++ b/src/Wpf.Ui/AutomationPeers/CardControlAutomationPeer.cs @@ -51,19 +51,19 @@ protected override AutomationPeer GetLabeledByCore() protected override string GetNameCore() { - var result = base.GetNameCore() ?? String.Empty; + var result = base.GetNameCore() ?? string.Empty; - if (result == String.Empty) + if (result == string.Empty) { result = AutomationProperties.GetName(_owner); } - if (result == String.Empty && _owner.Header is DependencyObject d) + if (result == string.Empty && _owner.Header is DependencyObject d) { result = AutomationProperties.GetName(d); } - if (result == String.Empty && _owner.Header is string s) + if (result == string.Empty && _owner.Header is string s) { result = s; } diff --git a/src/Wpf.Ui/ContentDialogService.cs b/src/Wpf.Ui/ContentDialogService.cs index 4be3b82a9..5476f3e91 100644 --- a/src/Wpf.Ui/ContentDialogService.cs +++ b/src/Wpf.Ui/ContentDialogService.cs @@ -32,42 +32,47 @@ namespace Wpf.Ui; /// public class ContentDialogService : IContentDialogService { - private ContentPresenter? _contentPresenter; + private ContentPresenter? _dialogHost; - /// + [Obsolete("Use SetDialogHost instead.")] public void SetContentPresenter(ContentPresenter contentPresenter) { - _contentPresenter = contentPresenter; + SetDialogHost(contentPresenter); + } + + [Obsolete("Use GetDialogHost instead.")] + public ContentPresenter? GetContentPresenter() + { + return GetDialogHost(); } /// - public ContentPresenter GetContentPresenter() + public void SetDialogHost(ContentPresenter contentPresenter) { - if (_contentPresenter is null) - { - throw new ArgumentNullException($"The ContentPresenter didn't set previously."); - } + _dialogHost = contentPresenter; + } - return _contentPresenter; + /// + public ContentPresenter? GetDialogHost() + { + return _dialogHost; } /// public Task ShowAsync(ContentDialog dialog, CancellationToken cancellationToken) { - if (_contentPresenter is null) + if (_dialogHost == null) { - throw new ArgumentNullException($"The ContentPresenter didn't set previously."); + throw new InvalidOperationException("The DialogHost was never set."); } - dialog.ContentPresenter ??= _contentPresenter; - - if (dialog.ContentPresenter != _contentPresenter) + if (dialog.DialogHost != null && _dialogHost != dialog.DialogHost) { - throw new InvalidOperationException( - $"The ContentPresenter is not the same as the previously set." - ); + throw new InvalidOperationException("The DialogHost is not the same as the one that was previously set."); } + dialog.DialogHost = _dialogHost; + return dialog.ShowAsync(cancellationToken); } } diff --git a/src/Wpf.Ui/Controls/Anchor/Anchor.cs b/src/Wpf.Ui/Controls/Anchor/Anchor.cs index 033626ee0..032009df4 100644 --- a/src/Wpf.Ui/Controls/Anchor/Anchor.cs +++ b/src/Wpf.Ui/Controls/Anchor/Anchor.cs @@ -2,8 +2,7 @@ // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - - +// // https://docs.microsoft.com/en-us/fluent-ui/web-components/components/anchor // ReSharper disable once CheckNamespace @@ -18,6 +17,4 @@ namespace Wpf.Ui.Controls; /// NavigateUri="https://dev.lepo.co/" /> /// /// -//[ToolboxItem(true)] -//[ToolboxBitmap(typeof(Anchor), "Anchor.bmp")] public class Anchor : Wpf.Ui.Controls.HyperlinkButton { } diff --git a/src/Wpf.Ui/Controls/Arc/Arc.cs b/src/Wpf.Ui/Controls/Arc/Arc.cs index ef3d37b4c..4d14713a8 100644 --- a/src/Wpf.Ui/Controls/Arc/Arc.cs +++ b/src/Wpf.Ui/Controls/Arc/Arc.cs @@ -22,13 +22,9 @@ namespace Wpf.Ui.Controls; /// Visibility="Visible" /> /// /// -// [ToolboxItem(true)] -// [ToolboxBitmap(typeof(Arc), "Arc.bmp")] public class Arc : System.Windows.Shapes.Shape { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty StartAngleProperty = DependencyProperty.Register( nameof(StartAngle), typeof(double), @@ -36,9 +32,7 @@ public class Arc : System.Windows.Shapes.Shape new PropertyMetadata(0.0d, PropertyChangedCallback) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty EndAngleProperty = DependencyProperty.Register( nameof(EndAngle), typeof(double), diff --git a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.cs b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.cs index 5c8ae6acb..d478e4a2c 100644 --- a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.cs +++ b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.cs @@ -27,22 +27,16 @@ namespace Wpf.Ui.Controls; /// </ui:AutoSuggestBox> /// /// -//[ToolboxItem(true)] -//[ToolboxBitmap(typeof(AutoSuggestBox), "AutoSuggestBox.bmp")] [TemplatePart(Name = ElementTextBox, Type = typeof(TextBox))] [TemplatePart(Name = ElementSuggestionsPopup, Type = typeof(Popup))] [TemplatePart(Name = ElementSuggestionsList, Type = typeof(ListView))] public class AutoSuggestBox : System.Windows.Controls.ItemsControl, IIconControl { protected const string ElementTextBox = "PART_TextBox"; - protected const string ElementSuggestionsPopup = "PART_SuggestionsPopup"; - protected const string ElementSuggestionsList = "PART_SuggestionsList"; - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty OriginalItemsSourceProperty = DependencyProperty.Register( nameof(OriginalItemsSource), typeof(IList), @@ -50,9 +44,7 @@ public class AutoSuggestBox : System.Windows.Controls.ItemsControl, IIconControl new PropertyMetadata(Array.Empty()) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IsSuggestionListOpenProperty = DependencyProperty.Register( nameof(IsSuggestionListOpen), typeof(bool), @@ -60,29 +52,23 @@ public class AutoSuggestBox : System.Windows.Controls.ItemsControl, IIconControl new PropertyMetadata(false) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty TextProperty = DependencyProperty.Register( nameof(Text), typeof(string), typeof(AutoSuggestBox), - new PropertyMetadata(String.Empty, TextPropertyChangedCallback) + new PropertyMetadata(string.Empty, OnTextChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty PlaceholderTextProperty = DependencyProperty.Register( nameof(PlaceholderText), typeof(string), typeof(AutoSuggestBox), - new PropertyMetadata(String.Empty) + new PropertyMetadata(string.Empty) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty UpdateTextOnSelectProperty = DependencyProperty.Register( nameof(UpdateTextOnSelect), typeof(bool), @@ -90,9 +76,7 @@ public class AutoSuggestBox : System.Windows.Controls.ItemsControl, IIconControl new PropertyMetadata(true) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty MaxSuggestionListHeightProperty = DependencyProperty.Register( nameof(MaxSuggestionListHeight), typeof(double), @@ -100,9 +84,7 @@ public class AutoSuggestBox : System.Windows.Controls.ItemsControl, IIconControl new PropertyMetadata(0d) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(IconElement), @@ -110,9 +92,7 @@ public class AutoSuggestBox : System.Windows.Controls.ItemsControl, IIconControl new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty FocusCommandProperty = DependencyProperty.Register( nameof(FocusCommand), typeof(ICommand), @@ -194,9 +174,7 @@ public IconElement? Icon /// public ICommand FocusCommand => (ICommand)GetValue(FocusCommandProperty); - /// - /// Routed event for . - /// + /// Identifies the routed event. public static readonly RoutedEvent QuerySubmittedEvent = EventManager.RegisterRoutedEvent( nameof(QuerySubmitted), RoutingStrategy.Bubble, @@ -204,9 +182,7 @@ public IconElement? Icon typeof(AutoSuggestBox) ); - /// - /// Routed event for . - /// + /// Identifies the routed event. public static readonly RoutedEvent SuggestionChosenEvent = EventManager.RegisterRoutedEvent( nameof(SuggestionChosen), RoutingStrategy.Bubble, @@ -214,9 +190,7 @@ public IconElement? Icon typeof(AutoSuggestBox) ); - /// - /// Routed event for . - /// + /// Identifies the routed event. public static readonly RoutedEvent TextChangedEvent = EventManager.RegisterRoutedEvent( nameof(TextChanged), RoutingStrategy.Bubble, @@ -251,18 +225,15 @@ public event TypedEventHandler RemoveHandler(TextChangedEvent, value); } - protected TextBox? TextBox = null; + protected TextBox? TextBox { get; set; } = null; - protected Popup SuggestionsPopup = null!; + protected Popup SuggestionsPopup { get; set; } = null!; - protected ListView? SuggestionsList = null!; + protected ListView? SuggestionsList { get; set; } = null!; private bool _changingTextAfterSuggestionChosen; - private bool _isChangedTextOutSideOfTextBox; - private object? _selectedItem; - private bool? _isHwndHookSubscribed; public AutoSuggestBox() @@ -297,9 +268,9 @@ public override void OnApplyTemplate() } /// - public new void Focus() + public new bool Focus() { - TextBox.Focus(); + return TextBox!.Focus(); } protected T GetTemplateChild(string name) @@ -433,16 +404,13 @@ private void TextBoxOnPreviewKeyDown(object sender, KeyEventArgs e) if (e.Key is Key.Escape) { SetCurrentValue(IsSuggestionListOpenProperty, false); - return; } if (e.Key is Key.Enter) { SetCurrentValue(IsSuggestionListOpenProperty, false); - - OnQuerySubmitted(TextBox.Text); - + OnQuerySubmitted(TextBox!.Text); return; } @@ -478,9 +446,9 @@ private void TextBoxOnTextChanged(object sender, TextChangedEventArgs e) changeReason = AutoSuggestionBoxTextChangeReason.ProgrammaticChange; } - OnTextChanged(changeReason, TextBox.Text); + OnTextChanged(changeReason, TextBox!.Text); - SuggestionsList.SetCurrentValue(Selector.SelectedItemProperty, null); + SuggestionsList!.SetCurrentValue(Selector.SelectedItemProperty, null); if (changeReason is not AutoSuggestionBoxTextChangeReason.UserInput) { @@ -509,12 +477,12 @@ private void SuggestionsListOnPreviewKeyDown(object sender, KeyEventArgs e) SetCurrentValue(IsSuggestionListOpenProperty, false); - OnSelectedChanged(SuggestionsList.SelectedItem); + OnSelectedChanged(SuggestionsList!.SelectedItem); } private void SuggestionsListOnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { - if (SuggestionsList.SelectedItem is not null) + if (SuggestionsList!.SelectedItem is not null) { return; } @@ -529,7 +497,7 @@ private void SuggestionsListOnPreviewMouseLeftButtonUp(object sender, MouseButto private void SuggestionsListOnSelectionChanged(object sender, SelectionChangedEventArgs e) { - if (SuggestionsList.SelectedItem is null) + if (SuggestionsList!.SelectedItem is null) { return; } @@ -565,61 +533,43 @@ private void UpdateTexBoxTextAfterSelection(object selectedObj) { _changingTextAfterSuggestionChosen = true; - TextBox.SetCurrentValue(System.Windows.Controls.TextBox.TextProperty, GetStringFromObj(selectedObj)); + TextBox!.SetCurrentValue(System.Windows.Controls.TextBox.TextProperty, GetStringFromObj(selectedObj)); _changingTextAfterSuggestionChosen = false; } private void DefaultFiltering(string text) { - if (String.IsNullOrEmpty(text)) + if (string.IsNullOrEmpty(text)) { SetCurrentValue(ItemsSourceProperty, OriginalItemsSource); - return; } - var suitableItems = new List(); - var splitText = text.ToLower().Split(' '); - - for (var i = 0; i < OriginalItemsSource.Count; i++) - { - var item = OriginalItemsSource[i]; - var itemText = GetStringFromObj(item); - - var found = splitText.All(key => itemText.ToLower().Contains(key)); - - if (found) + var splitText = text.ToLowerInvariant().Split(' '); + var suitableItems = OriginalItemsSource + .Cast() + .Where(item => { - suitableItems.Add(item); - } - } + var itemText = GetStringFromObj(item)?.ToLowerInvariant(); + return splitText.All(key => itemText?.Contains(key) ?? false); + }) + .ToList(); SetCurrentValue(ItemsSourceProperty, suitableItems); } private string? GetStringFromObj(object obj) { - var text = String.Empty; - - if (!String.IsNullOrEmpty(DisplayMemberPath)) - { - //Maybe it needs some optimization? - if (obj.GetType().GetProperty(DisplayMemberPath)?.GetValue(obj) is string value) - { - text = value; - } - } - - if (String.IsNullOrEmpty(text)) - { - text = obj as String ?? obj.ToString(); - } + // uses reflection. maybe it needs some optimization? + var displayMemberPathText = !string.IsNullOrEmpty(DisplayMemberPath) && obj.GetType().GetProperty(DisplayMemberPath)?.GetValue(obj) is string value + ? value + : null; - return text; + return displayMemberPathText ?? obj as string ?? obj.ToString(); } - private static void TextPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var self = (AutoSuggestBox)d; var newText = (string)e.NewValue; diff --git a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBoxTextChangedEventArgs.cs b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBoxTextChangedEventArgs.cs index 0aa4cfae9..87d82a490 100644 --- a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBoxTextChangedEventArgs.cs +++ b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBoxTextChangedEventArgs.cs @@ -15,5 +15,6 @@ public AutoSuggestBoxTextChangedEventArgs(RoutedEvent eventArgs, object sender) : base(eventArgs, sender) { } public required string Text { get; init; } + public required AutoSuggestionBoxTextChangeReason Reason { get; init; } } diff --git a/src/Wpf.Ui/Controls/Badge/Badge.cs b/src/Wpf.Ui/Controls/Badge/Badge.cs index 2906ee02f..cebd04cdb 100644 --- a/src/Wpf.Ui/Controls/Badge/Badge.cs +++ b/src/Wpf.Ui/Controls/Badge/Badge.cs @@ -2,7 +2,7 @@ // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - +// // https://docs.microsoft.com/en-us/fluent-ui/web-components/components/badge // ReSharper disable once CheckNamespace @@ -18,13 +18,9 @@ namespace Wpf.Ui.Controls; /// </ui:Badge> /// /// -//[ToolboxItem(true)] -//[ToolboxBitmap(typeof(Badge), "Badge.bmp")] public class Badge : System.Windows.Controls.ContentControl, IAppearanceControl { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty AppearanceProperty = DependencyProperty.Register( nameof(Appearance), typeof(Controls.ControlAppearance), diff --git a/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBar.cs b/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBar.cs index cd592e864..9e1e4739e 100644 --- a/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBar.cs +++ b/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBar.cs @@ -2,7 +2,7 @@ // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - +// // Based on Windows UI Library // Copyright(c) Microsoft Corporation.All rights reserved. @@ -25,9 +25,7 @@ namespace Wpf.Ui.Controls; [StyleTypedProperty(Property = nameof(ItemContainerStyle), StyleTargetType = typeof(BreadcrumbBarItem))] public class BreadcrumbBar : System.Windows.Controls.ItemsControl { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty CommandProperty = DependencyProperty.Register( nameof(Command), typeof(ICommand), @@ -35,9 +33,7 @@ public class BreadcrumbBar : System.Windows.Controls.ItemsControl new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty TemplateButtonCommandProperty = DependencyProperty.Register( nameof(TemplateButtonCommand), typeof(IRelayCommand), @@ -50,10 +46,8 @@ public class BreadcrumbBar : System.Windows.Controls.ItemsControl /// public IRelayCommand TemplateButtonCommand => (IRelayCommand)GetValue(TemplateButtonCommandProperty); - /// - /// Property for . - /// - public static readonly RoutedEvent ItemClickedRoutedEvent = EventManager.RegisterRoutedEvent( + /// Identifies the routed event. + public static readonly RoutedEvent ItemClickedEvent = EventManager.RegisterRoutedEvent( nameof(ItemClicked), RoutingStrategy.Bubble, typeof(TypedEventHandler), @@ -66,9 +60,9 @@ public class BreadcrumbBar : System.Windows.Controls.ItemsControl [Bindable(true)] [Category("Action")] [Localizability(LocalizationCategory.NeverLocalize)] - public ICommand Command + public ICommand? Command { - get => (ICommand)GetValue(CommandProperty); + get => (ICommand?)GetValue(CommandProperty); set => SetValue(CommandProperty, value); } @@ -77,8 +71,8 @@ public ICommand Command /// public event TypedEventHandler ItemClicked { - add => AddHandler(ItemClickedRoutedEvent, value); - remove => RemoveHandler(ItemClickedRoutedEvent, value); + add => AddHandler(ItemClickedEvent, value); + remove => RemoveHandler(ItemClickedEvent, value); } /// @@ -94,7 +88,7 @@ public BreadcrumbBar() protected virtual void OnItemClicked(object item, int index) { - var args = new BreadcrumbBarItemClickedEventArgs(ItemClickedRoutedEvent, this, item, index); + var args = new BreadcrumbBarItemClickedEventArgs(ItemClickedEvent, this, item, index); RaiseEvent(args); if (Command?.CanExecute(item) ?? false) @@ -149,7 +143,7 @@ private void ItemContainerGeneratorOnStatusChanged(object? sender, EventArgs e) return; } - InteractWithItemContainer(2, static item => item.IsLast = false); + InteractWithItemContainer(2, static item => item.SetCurrentValue(BreadcrumbBarItem.IsLastProperty, false)); UpdateLastContainer(); } @@ -179,7 +173,9 @@ private void OnTemplateButtonClick(object? obj) private void InteractWithItemContainer(int offsetFromEnd, Action action) { if (ItemContainerGenerator.Items.Count <= 0) + { return; + } var item = ItemContainerGenerator.Items[^offsetFromEnd]; var container = (BreadcrumbBarItem)ItemContainerGenerator.ContainerFromItem(item); @@ -187,5 +183,6 @@ private void InteractWithItemContainer(int offsetFromEnd, Action InteractWithItemContainer(1, static item => item.IsLast = true); + private void UpdateLastContainer() + => InteractWithItemContainer(1, static item => item.SetCurrentValue(BreadcrumbBarItem.IsLastProperty, true)); } diff --git a/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBarItem.cs b/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBarItem.cs index d81c8059a..ea6d82561 100644 --- a/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBarItem.cs +++ b/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBarItem.cs @@ -2,9 +2,8 @@ // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - +// // Based on Windows UI Library -// Copyright(c) Microsoft Corporation.All rights reserved. using Wpf.Ui.Converters; @@ -16,19 +15,15 @@ namespace Wpf.Ui.Controls; /// public class BreadcrumbBarItem : System.Windows.Controls.ContentControl { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(IconElement), typeof(BreadcrumbBarItem), - new PropertyMetadata(null, null, IconSourceElementConverter.ConvertToIconElement) + new PropertyMetadata(null, null, IconElement.Coerce) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IconMarginProperty = DependencyProperty.Register( nameof(IconMargin), typeof(Thickness), @@ -36,9 +31,7 @@ public class BreadcrumbBarItem : System.Windows.Controls.ContentControl new PropertyMetadata(new Thickness(0)) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IsLastProperty = DependencyProperty.Register( nameof(IsLast), typeof(bool), @@ -51,12 +44,12 @@ public class BreadcrumbBarItem : System.Windows.Controls.ContentControl /// public IconElement? Icon { - get => (IconElement)GetValue(IconProperty); + get => (IconElement?)GetValue(IconProperty); set => SetValue(IconProperty, value); } /// - /// Get or sets margin for the + /// Gets or sets get or sets margin for the /// public Thickness IconMargin { @@ -65,7 +58,7 @@ public Thickness IconMargin } /// - /// Whether the current item is the last one. + /// Gets or sets a value indicating whether the current item is the last one. /// public bool IsLast { diff --git a/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBarItemClickedEventArgs.cs b/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBarItemClickedEventArgs.cs index f680d12c4..ba3efbb22 100644 --- a/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBarItemClickedEventArgs.cs +++ b/src/Wpf.Ui/Controls/BreadcrumbBar/BreadcrumbBarItemClickedEventArgs.cs @@ -2,7 +2,7 @@ // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. - +// // Based on Windows UI Library // Copyright(c) Microsoft Corporation.All rights reserved. diff --git a/src/Wpf.Ui/Controls/Button/Button.cs b/src/Wpf.Ui/Controls/Button/Button.cs index 8da7aab40..fd14c98fa 100644 --- a/src/Wpf.Ui/Controls/Button/Button.cs +++ b/src/Wpf.Ui/Controls/Button/Button.cs @@ -4,7 +4,6 @@ // All Rights Reserved. using System.Windows.Controls; -using Wpf.Ui.Converters; // ReSharper disable once CheckNamespace namespace Wpf.Ui.Controls; @@ -31,19 +30,15 @@ namespace Wpf.Ui.Controls; /// public class Button : System.Windows.Controls.Button, IAppearanceControl, IIconControl { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(IconElement), typeof(Button), - new PropertyMetadata(null, null, IconSourceElementConverter.ConvertToIconElement) + new PropertyMetadata(null, null, IconElement.Coerce) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty AppearanceProperty = DependencyProperty.Register( nameof(Appearance), typeof(ControlAppearance), @@ -51,9 +46,7 @@ public class Button : System.Windows.Controls.Button, IAppearanceControl, IIconC new PropertyMetadata(ControlAppearance.Primary) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.Register( nameof(MouseOverBackground), typeof(Brush), @@ -61,9 +54,7 @@ public class Button : System.Windows.Controls.Button, IAppearanceControl, IIconC new PropertyMetadata(Border.BackgroundProperty.DefaultMetadata.DefaultValue) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty MouseOverBorderBrushProperty = DependencyProperty.Register( nameof(MouseOverBorderBrush), typeof(Brush), @@ -71,9 +62,7 @@ public class Button : System.Windows.Controls.Button, IAppearanceControl, IIconC new PropertyMetadata(Border.BorderBrushProperty.DefaultMetadata.DefaultValue) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty PressedForegroundProperty = DependencyProperty.Register( nameof(PressedForeground), typeof(Brush), @@ -84,9 +73,7 @@ public class Button : System.Windows.Controls.Button, IAppearanceControl, IIconC ) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty PressedBackgroundProperty = DependencyProperty.Register( nameof(PressedBackground), typeof(Brush), @@ -94,9 +81,7 @@ public class Button : System.Windows.Controls.Button, IAppearanceControl, IIconC new PropertyMetadata(Border.BackgroundProperty.DefaultMetadata.DefaultValue) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty PressedBorderBrushProperty = DependencyProperty.Register( nameof(PressedBorderBrush), typeof(Brush), @@ -104,33 +89,31 @@ public class Button : System.Windows.Controls.Button, IAppearanceControl, IIconC new PropertyMetadata(Border.BorderBrushProperty.DefaultMetadata.DefaultValue) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register( nameof(CornerRadius), typeof(CornerRadius), typeof(Button), - (PropertyMetadata) - new FrameworkPropertyMetadata( - (object)new CornerRadius(), - FrameworkPropertyMetadataOptions.AffectsMeasure - | FrameworkPropertyMetadataOptions.AffectsRender - ) + new FrameworkPropertyMetadata( + default(CornerRadius), + FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender + ) ); /// /// Gets or sets displayed . /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public IconElement? Icon { - get => (IconElement)GetValue(IconProperty); + get => (IconElement?)GetValue(IconProperty); set => SetValue(IconProperty, value); } /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public ControlAppearance Appearance { get => (ControlAppearance)GetValue(AppearanceProperty); @@ -138,9 +121,10 @@ public ControlAppearance Appearance } /// - /// Background when the user interacts with an element with a pointing device. + /// Gets or sets background . /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public Brush MouseOverBackground { get => (Brush)GetValue(MouseOverBackgroundProperty); @@ -148,9 +132,10 @@ public Brush MouseOverBackground } /// - /// Border when the user interacts with an element with a pointing device. + /// Gets or sets border when the user mouses over the button. /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public Brush MouseOverBorderBrush { get => (Brush)GetValue(MouseOverBorderBrushProperty); @@ -158,9 +143,10 @@ public Brush MouseOverBorderBrush } /// - /// Foreground when pressed. + /// Gets or sets the foreground when the user clicks the button. /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public Brush PressedForeground { get => (Brush)GetValue(PressedForegroundProperty); @@ -168,9 +154,10 @@ public Brush PressedForeground } /// - /// Background when the user clicks the button. + /// Gets or sets background when the user clicks the button. /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public Brush PressedBackground { get => (Brush)GetValue(PressedBackgroundProperty); @@ -178,9 +165,10 @@ public Brush PressedBackground } /// - /// Border when the user clicks the button. + /// Gets or sets border when the user clicks the button. /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public Brush PressedBorderBrush { get => (Brush)GetValue(PressedBorderBrushProperty); diff --git a/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.cs b/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.cs index 09a60a97d..1267a64c0 100644 --- a/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.cs +++ b/src/Wpf.Ui/Controls/CalendarDatePicker/CalendarDatePicker.cs @@ -23,9 +23,7 @@ public class CalendarDatePicker : Wpf.Ui.Controls.Button { private Popup? _popup; - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IsCalendarOpenProperty = DependencyProperty.Register( nameof(IsCalendarOpen), typeof(bool), @@ -33,9 +31,7 @@ public class CalendarDatePicker : Wpf.Ui.Controls.Button new PropertyMetadata(false) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IsTodayHighlightedProperty = DependencyProperty.Register( nameof(IsTodayHighlighted), typeof(bool), @@ -43,9 +39,7 @@ public class CalendarDatePicker : Wpf.Ui.Controls.Button new PropertyMetadata(false) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty DateProperty = DependencyProperty.Register( nameof(Date), typeof(DateTime?), @@ -53,9 +47,7 @@ public class CalendarDatePicker : Wpf.Ui.Controls.Button new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty FirstDayOfWeekProperty = DependencyProperty.Register( nameof(FirstDayOfWeek), typeof(DayOfWeek), diff --git a/src/Wpf.Ui/Controls/Card/Card.cs b/src/Wpf.Ui/Controls/Card/Card.cs index 0b9045201..c0656e058 100644 --- a/src/Wpf.Ui/Controls/Card/Card.cs +++ b/src/Wpf.Ui/Controls/Card/Card.cs @@ -9,23 +9,17 @@ namespace Wpf.Ui.Controls; /// /// Simple Card with content and . /// -//[ToolboxItem(true)] -//[ToolboxBitmap(typeof(Card), "Card.bmp")] public class Card : System.Windows.Controls.ContentControl { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty FooterProperty = DependencyProperty.Register( nameof(Footer), typeof(object), typeof(Card), - new PropertyMetadata(null, FooterChangedCallback) + new PropertyMetadata(null, OnFooterChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty HasFooterProperty = DependencyProperty.Register( nameof(HasFooter), typeof(bool), @@ -36,14 +30,14 @@ public class Card : System.Windows.Controls.ContentControl /// /// Gets or sets additional content displayed at the bottom. /// - public object Footer + public object? Footer { get => GetValue(FooterProperty); set => SetValue(FooterProperty, value); } /// - /// Gets information whether the has a . + /// Gets a value indicating whether the has a . /// public bool HasFooter { @@ -51,10 +45,12 @@ public bool HasFooter internal set => SetValue(HasFooterProperty, value); } - private static void FooterChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnFooterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not Card control) + { return; + } control.SetValue(HasFooterProperty, control.Footer != null); } diff --git a/src/Wpf.Ui/Controls/CardAction/CardAction.cs b/src/Wpf.Ui/Controls/CardAction/CardAction.cs index 18fcdecf3..dc73e9189 100644 --- a/src/Wpf.Ui/Controls/CardAction/CardAction.cs +++ b/src/Wpf.Ui/Controls/CardAction/CardAction.cs @@ -3,24 +3,15 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. -using Wpf.Ui.Converters; - // ReSharper disable once CheckNamespace namespace Wpf.Ui.Controls; /// /// Inherited from the interactive card styled according to Fluent Design. /// -//#if NETFRAMEWORK -// //[ToolboxBitmap(typeof(Button))] -//#endif -//[ToolboxItem(true)] -//[ToolboxBitmap(typeof(CardAction), "CardAction.bmp")] public class CardAction : System.Windows.Controls.Primitives.ButtonBase { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IsChevronVisibleProperty = DependencyProperty.Register( nameof(IsChevronVisible), typeof(bool), @@ -28,20 +19,19 @@ public class CardAction : System.Windows.Controls.Primitives.ButtonBase new PropertyMetadata(true) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(IconElement), typeof(CardAction), - new PropertyMetadata(null, null, IconSourceElementConverter.ConvertToIconElement) + new PropertyMetadata(null, null, IconElement.Coerce) ); /// - /// Gets or sets information whether to display the chevron icon on the right side of the card. + /// Gets or sets a value indicating whether to display the chevron icon on the right side of the card. /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public bool IsChevronVisible { get => (bool)GetValue(IsChevronVisibleProperty); @@ -51,10 +41,11 @@ public bool IsChevronVisible /// /// Gets or sets displayed . /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public IconElement? Icon { - get => (IconElement)GetValue(IconProperty); + get => (IconElement?)GetValue(IconProperty); set => SetValue(IconProperty, value); } } diff --git a/src/Wpf.Ui/Controls/CardColor/CardColor.cs b/src/Wpf.Ui/Controls/CardColor/CardColor.cs index 26f302bc3..1a7606c91 100644 --- a/src/Wpf.Ui/Controls/CardColor/CardColor.cs +++ b/src/Wpf.Ui/Controls/CardColor/CardColor.cs @@ -11,29 +11,23 @@ namespace Wpf.Ui.Controls; /// public class CardColor : System.Windows.Controls.Control { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( nameof(Title), typeof(string), typeof(CardColor), - new PropertyMetadata(String.Empty) + new PropertyMetadata(string.Empty) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty SubtitleProperty = DependencyProperty.Register( nameof(Subtitle), typeof(string), typeof(CardColor), - new PropertyMetadata(String.Empty, OnSubtitlePropertyChanged) + new PropertyMetadata(string.Empty, OnSubtitleChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty SubtitleFontSizeProperty = DependencyProperty.Register( nameof(SubtitleFontSize), typeof(double), @@ -41,37 +35,31 @@ public class CardColor : System.Windows.Controls.Control new PropertyMetadata(11.0d) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty ColorProperty = DependencyProperty.Register( nameof(Color), typeof(Color), typeof(CardColor), - new PropertyMetadata(Color.FromArgb(0, 0, 0, 0), OnColorPropertyChanged) + new PropertyMetadata(Color.FromArgb(0, 0, 0, 0), OnColorChanged) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty BrushProperty = DependencyProperty.Register( nameof(Brush), typeof(Brush), typeof(CardColor), new PropertyMetadata( - new SolidColorBrush { Color = Color.FromArgb(0, 0, 0, 0) }, - OnBrushPropertyChanged + Brushes.Transparent, + OnBrushChanged ) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty CardBrushProperty = DependencyProperty.Register( nameof(CardBrush), typeof(Brush), typeof(CardColor), - new PropertyMetadata(new SolidColorBrush { Color = Color.FromArgb(0, 0, 0, 0) }) + new PropertyMetadata(Brushes.Transparent) ); /// @@ -138,7 +126,7 @@ protected virtual void OnSubtitlePropertyChanged() { } /// protected virtual void OnColorPropertyChanged() { - CardBrush = new SolidColorBrush(Color); + SetCurrentValue(CardBrushProperty, new SolidColorBrush(Color)); } /// @@ -146,29 +134,35 @@ protected virtual void OnColorPropertyChanged() /// protected virtual void OnBrushPropertyChanged() { - CardBrush = Brush; + SetCurrentValue(CardBrushProperty, Brush); } - private static void OnSubtitlePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnSubtitleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not CardColor cardColor) + { return; + } cardColor.OnSubtitlePropertyChanged(); } - private static void OnColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not CardColor cardColor) + { return; + } cardColor.OnColorPropertyChanged(); } - private static void OnBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not CardColor cardColor) + { return; + } cardColor.OnBrushPropertyChanged(); } diff --git a/src/Wpf.Ui/Controls/CardControl/CardControl.cs b/src/Wpf.Ui/Controls/CardControl/CardControl.cs index eacd0f80f..9d1a06a64 100644 --- a/src/Wpf.Ui/Controls/CardControl/CardControl.cs +++ b/src/Wpf.Ui/Controls/CardControl/CardControl.cs @@ -3,8 +3,6 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. -using System.ComponentModel; -using System.Windows; using System.Windows.Automation.Peers; using Wpf.Ui.AutomationPeers; @@ -15,9 +13,7 @@ namespace Wpf.Ui.Controls; /// public class CardControl : System.Windows.Controls.Primitives.ButtonBase, IIconControl { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register( nameof(Header), typeof(object), @@ -25,9 +21,7 @@ public class CardControl : System.Windows.Controls.Primitives.ButtonBase, IIconC new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(IconElement), @@ -35,9 +29,7 @@ public class CardControl : System.Windows.Controls.Primitives.ButtonBase, IIconC new PropertyMetadata(null) ); - /// - /// Property for - /// + /// Identifies the dependency property. public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register( nameof(CornerRadius), typeof(CornerRadius), @@ -46,10 +38,10 @@ public class CardControl : System.Windows.Controls.Primitives.ButtonBase, IIconC ); /// - /// Header is the data used to for the header of each item in the control. + /// Gets or sets header which is used for each item in the control. /// [Bindable(true)] - public object Header + public object? Header { get => GetValue(HeaderProperty); set => SetValue(HeaderProperty, value); @@ -58,17 +50,19 @@ public object Header /// /// Gets or sets displayed . /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public IconElement? Icon { - get => (IconElement)GetValue(IconProperty); + get => (IconElement?)GetValue(IconProperty); set => SetValue(IconProperty, value); } /// /// Gets or sets the corner radius of the control. /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public CornerRadius CornerRadius { get => (CornerRadius)GetValue(CornerRadiusProperty); diff --git a/src/Wpf.Ui/Controls/CardExpander/CardExpander.cs b/src/Wpf.Ui/Controls/CardExpander/CardExpander.cs index 6a620655b..d4c64c246 100644 --- a/src/Wpf.Ui/Controls/CardExpander/CardExpander.cs +++ b/src/Wpf.Ui/Controls/CardExpander/CardExpander.cs @@ -3,31 +3,23 @@ // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. -using Wpf.Ui.Converters; - // ReSharper disable once CheckNamespace namespace Wpf.Ui.Controls; /// /// Inherited from the control which can hide the collapsible content. /// -//[ToolboxItem(true)] -//[ToolboxBitmap(typeof(CardExpander), "CardExpander.bmp")] public class CardExpander : System.Windows.Controls.Expander { - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(IconElement), typeof(CardExpander), - new PropertyMetadata(null, null, IconSourceElementConverter.ConvertToIconElement) + new PropertyMetadata(null, null, IconElement.Coerce) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register( nameof(CornerRadius), typeof(CornerRadius), @@ -35,9 +27,7 @@ public class CardExpander : System.Windows.Controls.Expander new PropertyMetadata(new CornerRadius(4)) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty ContentPaddingProperty = DependencyProperty.Register( nameof(ContentPadding), typeof(Thickness), @@ -51,18 +41,20 @@ public class CardExpander : System.Windows.Controls.Expander /// /// Gets or sets displayed . /// - [Bindable(true), Category("Appearance")] + [Bindable(true)] + [Category("Appearance")] public IconElement? Icon { - get => (IconElement)GetValue(IconProperty); + get => (IconElement?)GetValue(IconProperty); set => SetValue(IconProperty, value); } /// /// Gets or sets displayed . /// - [Bindable(true), Category("Appearance")] - public CornerRadius? CornerRadius + [Bindable(true)] + [Category("Appearance")] + public CornerRadius CornerRadius { get => (CornerRadius)GetValue(CornerRadiusProperty); set => SetValue(CornerRadiusProperty, value); @@ -71,7 +63,8 @@ public CornerRadius? CornerRadius /// /// Gets or sets content padding Property /// - [Bindable(true), Category("Layout")] + [Bindable(true)] + [Category("Layout")] public Thickness ContentPadding { get { return (Thickness)GetValue(ContentPaddingProperty); } diff --git a/src/Wpf.Ui/Controls/ClientAreaBorder/ClientAreaBorder.cs b/src/Wpf.Ui/Controls/ClientAreaBorder/ClientAreaBorder.cs index 39c419cbf..cc6d6d638 100644 --- a/src/Wpf.Ui/Controls/ClientAreaBorder/ClientAreaBorder.cs +++ b/src/Wpf.Ui/Controls/ClientAreaBorder/ClientAreaBorder.cs @@ -43,26 +43,19 @@ namespace Wpf.Ui.Controls; /// public class ClientAreaBorder : System.Windows.Controls.Border, IThemeControl { - private bool _borderBrushApplied = false; - - private const int SM_CXFRAME = 32; - + /*private const int SM_CXFRAME = 32; private const int SM_CYFRAME = 33; - - private const int SM_CXPADDEDBORDER = 92; - - private System.Windows.Window? _oldWindow; - + private const int SM_CXPADDEDBORDER = 92;*/ private static Thickness? _paddedBorderThickness; - private static Thickness? _resizeFrameBorderThickness; - private static Thickness? _windowChromeNonClientFrameThickness; + private bool _borderBrushApplied = false; + private System.Windows.Window? _oldWindow; public ApplicationTheme ApplicationTheme { get; set; } = ApplicationTheme.Unknown; /// - /// Get the system value in WPF units. + /// Gets the system value for the padded border thickness () in WPF units. /// public Thickness PaddedBorderThickness { @@ -92,9 +85,9 @@ public Thickness PaddedBorderThickness } /// - /// Get the system and values in WPF units. + /// Gets the system and values in WPF units. /// - public Thickness ResizeFrameBorderThickness => + public static Thickness ResizeFrameBorderThickness => _resizeFrameBorderThickness ??= new Thickness( SystemParameters.ResizeFrameVerticalBorderWidth, SystemParameters.ResizeFrameHorizontalBorderHeight, @@ -103,16 +96,19 @@ public Thickness PaddedBorderThickness ); /// + /// Gets the thickness of the window's non-client frame used for maximizing the window with a custom chrome. + /// + /// /// If you use a to extend the client area of a window to the non-client area, you need to handle the edge margin issue when the window is maximized. /// Use this property to get the correct margin value when the window is maximized, so that when the window is maximized, the client area can completely cover the screen client area by no less than a single pixel at any DPI. /// The method cannot obtain this value directly. - /// + /// public Thickness WindowChromeNonClientFrameThickness => _windowChromeNonClientFrameThickness ??= new Thickness( - ResizeFrameBorderThickness.Left + PaddedBorderThickness.Left, - ResizeFrameBorderThickness.Top + PaddedBorderThickness.Top, - ResizeFrameBorderThickness.Right + PaddedBorderThickness.Right, - ResizeFrameBorderThickness.Bottom + PaddedBorderThickness.Bottom + ClientAreaBorder.ResizeFrameBorderThickness.Left + PaddedBorderThickness.Left, + ClientAreaBorder.ResizeFrameBorderThickness.Top + PaddedBorderThickness.Top, + ClientAreaBorder.ResizeFrameBorderThickness.Right + PaddedBorderThickness.Right, + ClientAreaBorder.ResizeFrameBorderThickness.Bottom + PaddedBorderThickness.Bottom ); public ClientAreaBorder() @@ -174,11 +170,8 @@ private void OnWindowStateChanged(object? sender, EventArgs e) return; } - Padding = window.WindowState switch - { - WindowState.Maximized => WindowChromeNonClientFrameThickness, - _ => default, - }; + Thickness padding = window.WindowState == WindowState.Maximized ? WindowChromeNonClientFrameThickness : default; + SetCurrentValue(PaddingProperty, padding); } private void ApplyDefaultWindowBorder() @@ -191,15 +184,14 @@ private void ApplyDefaultWindowBorder() _borderBrushApplied = true; // SystemParameters.WindowGlassBrush - _oldWindow.BorderThickness = new Thickness(1); - _oldWindow.BorderBrush = new SolidColorBrush( - ApplicationTheme == ApplicationTheme.Light - ? Color.FromArgb(0xFF, 0x7A, 0x7A, 0x7A) - : Color.FromArgb(0xFF, 0x3A, 0x3A, 0x3A) - ); + Color borderColor = ApplicationTheme == ApplicationTheme.Light + ? Color.FromArgb(0xFF, 0x7A, 0x7A, 0x7A) + : Color.FromArgb(0xFF, 0x3A, 0x3A, 0x3A); + _oldWindow.SetCurrentValue(System.Windows.Controls.Control.BorderBrushProperty, new SolidColorBrush(borderColor)); + _oldWindow.SetCurrentValue(System.Windows.Controls.Control.BorderThicknessProperty, new Thickness(1)); } - private (double factorX, double factorY) GetDpi() + private (double FactorX, double FactorY) GetDpi() { if (PresentationSource.FromVisual(this) is { } source) { diff --git a/src/Wpf.Ui/Controls/ContentDialog/ContentDialog.cs b/src/Wpf.Ui/Controls/ContentDialog/ContentDialog.cs index 5d72a436f..285fc848b 100644 --- a/src/Wpf.Ui/Controls/ContentDialog/ContentDialog.cs +++ b/src/Wpf.Ui/Controls/ContentDialog/ContentDialog.cs @@ -43,11 +43,7 @@ namespace Wpf.Ui.Controls; /// public class ContentDialog : ContentControl { - #region Static properties - - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( nameof(Title), typeof(object), @@ -55,9 +51,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty TitleTemplateProperty = DependencyProperty.Register( nameof(TitleTemplate), typeof(DataTemplate), @@ -65,78 +59,62 @@ public class ContentDialog : ContentControl new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty DialogWidthProperty = DependencyProperty.Register( nameof(DialogWidth), typeof(double), typeof(ContentDialog), - new PropertyMetadata(Double.PositiveInfinity) + new PropertyMetadata(double.PositiveInfinity) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty DialogHeightProperty = DependencyProperty.Register( nameof(DialogHeight), typeof(double), typeof(ContentDialog), - new PropertyMetadata(Double.PositiveInfinity) + new PropertyMetadata(double.PositiveInfinity) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty DialogMaxWidthProperty = DependencyProperty.Register( nameof(DialogMaxWidth), typeof(double), typeof(ContentDialog), - new PropertyMetadata(Double.PositiveInfinity) + new PropertyMetadata(double.PositiveInfinity) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty DialogMaxHeightProperty = DependencyProperty.Register( nameof(DialogMaxHeight), typeof(double), typeof(ContentDialog), - new PropertyMetadata(Double.PositiveInfinity) + new PropertyMetadata(double.PositiveInfinity) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty DialogMarginProperty = DependencyProperty.Register( nameof(DialogMargin), typeof(Thickness), typeof(ContentDialog) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty PrimaryButtonTextProperty = DependencyProperty.Register( nameof(PrimaryButtonText), typeof(string), typeof(ContentDialog), - new PropertyMetadata(String.Empty) + new PropertyMetadata(string.Empty) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty SecondaryButtonTextProperty = DependencyProperty.Register( nameof(SecondaryButtonText), typeof(string), typeof(ContentDialog), - new PropertyMetadata(String.Empty) + new PropertyMetadata(string.Empty) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty CloseButtonTextProperty = DependencyProperty.Register( nameof(CloseButtonText), typeof(string), @@ -144,9 +122,7 @@ public class ContentDialog : ContentControl new PropertyMetadata("Close") ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty PrimaryButtonIconProperty = DependencyProperty.Register( nameof(PrimaryButtonIcon), typeof(IconElement), @@ -154,9 +130,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty SecondaryButtonIconProperty = DependencyProperty.Register( nameof(SecondaryButtonIcon), typeof(IconElement), @@ -164,9 +138,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty CloseButtonIconProperty = DependencyProperty.Register( nameof(CloseButtonIcon), typeof(IconElement), @@ -174,9 +146,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IsPrimaryButtonEnabledProperty = DependencyProperty.Register( nameof(IsPrimaryButtonEnabled), typeof(bool), @@ -184,9 +154,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(true) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IsSecondaryButtonEnabledProperty = DependencyProperty.Register( nameof(IsSecondaryButtonEnabled), typeof(bool), @@ -194,9 +162,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(true) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty PrimaryButtonAppearanceProperty = DependencyProperty.Register( nameof(PrimaryButtonAppearance), typeof(ControlAppearance), @@ -204,9 +170,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(ControlAppearance.Primary) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty SecondaryButtonAppearanceProperty = DependencyProperty.Register( nameof(SecondaryButtonAppearance), typeof(ControlAppearance), @@ -214,9 +178,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(ControlAppearance.Secondary) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty CloseButtonAppearanceProperty = DependencyProperty.Register( nameof(CloseButtonAppearance), typeof(ControlAppearance), @@ -224,9 +186,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(ControlAppearance.Secondary) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty DefaultButtonProperty = DependencyProperty.Register( nameof(DefaultButton), typeof(ContentDialogButton), @@ -234,9 +194,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(ContentDialogButton.Primary) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty IsFooterVisibleProperty = DependencyProperty.Register( nameof(IsFooterVisible), typeof(bool), @@ -244,9 +202,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(true) ); - /// - /// Property for . - /// + /// Identifies the dependency property. public static readonly DependencyProperty TemplateButtonCommandProperty = DependencyProperty.Register( nameof(TemplateButtonCommand), typeof(IRelayCommand), @@ -254,9 +210,7 @@ public class ContentDialog : ContentControl new PropertyMetadata(null) ); - /// - /// Property for . - /// + /// Identifies the routed event. public static readonly RoutedEvent OpenedEvent = EventManager.RegisterRoutedEvent( nameof(Opened), RoutingStrategy.Bubble, @@ -264,9 +218,7 @@ public class ContentDialog : ContentControl typeof(ContentDialog) ); - /// - /// Property for . - /// + /// Identifies the routed event. public static readonly RoutedEvent ClosingEvent = EventManager.RegisterRoutedEvent( nameof(Closing), RoutingStrategy.Bubble, @@ -274,9 +226,7 @@ public class ContentDialog : ContentControl typeof(ContentDialog) ); - /// - /// Property for . - /// + /// Identifies the routed event. public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent( nameof(Closed), RoutingStrategy.Bubble, @@ -284,9 +234,7 @@ public class ContentDialog : ContentControl typeof(ContentDialog) ); - /// - /// Property for . - /// + /// Identifies the routed event. public static readonly RoutedEvent ButtonClickedEvent = EventManager.RegisterRoutedEvent( nameof(ButtonClicked), RoutingStrategy.Bubble, @@ -294,14 +242,10 @@ public class ContentDialog : ContentControl typeof(ContentDialog) ); - #endregion - - #region Properties - /// /// Gets or sets the title of the . /// - public object Title + public object? Title { get => GetValue(TitleProperty); set => SetValue(TitleProperty, value); @@ -310,9 +254,9 @@ public object Title /// /// Gets or sets the title template of the . /// - public DataTemplate TitleTemplate + public DataTemplate? TitleTemplate { - get => (DataTemplate)GetValue(TitleTemplateProperty); + get => (DataTemplate?)GetValue(TitleTemplateProperty); set => SetValue(TitleTemplateProperty, value); } @@ -393,7 +337,7 @@ public string CloseButtonText /// public IconElement? PrimaryButtonIcon { - get => (IconElement)GetValue(PrimaryButtonIconProperty); + get => (IconElement?)GetValue(PrimaryButtonIconProperty); set => SetValue(PrimaryButtonIconProperty, value); } @@ -402,7 +346,7 @@ public IconElement? PrimaryButtonIcon /// public IconElement? SecondaryButtonIcon { - get => (IconElement)GetValue(SecondaryButtonIconProperty); + get => (IconElement?)GetValue(SecondaryButtonIconProperty); set => SetValue(SecondaryButtonIconProperty, value); } @@ -411,12 +355,12 @@ public IconElement? SecondaryButtonIcon /// public IconElement? CloseButtonIcon { - get => (IconElement)GetValue(CloseButtonIconProperty); + get => (IconElement?)GetValue(CloseButtonIconProperty); set => SetValue(CloseButtonIconProperty, value); } /// - /// Gets or sets whether the primary button is enabled. + /// Gets or sets a value indicating whether the primary button is enabled. /// public bool IsPrimaryButtonEnabled { @@ -425,7 +369,7 @@ public bool IsPrimaryButtonEnabled } /// - /// Gets or sets whether the secondary button is enabled. + /// Gets or sets a value indicating whether the secondary button is enabled. /// public bool IsSecondaryButtonEnabled { @@ -470,7 +414,7 @@ public ContentDialogButton DefaultButton } /// - /// Gets or sets a value that indicates the visibility of the footer buttons. + /// Gets or sets a value indicating whether the footer buttons are visible. /// public bool IsFooterVisible { @@ -479,7 +423,7 @@ public bool IsFooterVisible } /// - /// Command triggered after clicking the button in the template. + /// Gets command triggered after clicking the button in the template. /// public IRelayCommand TemplateButtonCommand => (IRelayCommand)GetValue(TemplateButtonCommandProperty); @@ -519,8 +463,6 @@ public event TypedEventHandler remove => RemoveHandler(ButtonClickedEvent, value); } - #endregion - /// /// Initializes a new instance of the class. /// @@ -538,10 +480,15 @@ public ContentDialog() /// /// Initializes a new instance of the class. /// - /// inside of which the dialogue will be placed. The new will replace the current . - public ContentDialog(ContentPresenter contentPresenter) + /// inside of which the dialogue will be placed. The new will replace the current . + public ContentDialog(ContentPresenter? dialogHost) { - ContentPresenter = contentPresenter; + if (dialogHost is null) + { + throw new ArgumentNullException(nameof(dialogHost)); + } + + DialogHost = dialogHost; SetValue(TemplateButtonCommandProperty, new RelayCommand(OnButtonClick)); @@ -553,22 +500,24 @@ public ContentDialog(ContentPresenter contentPresenter) } /// - /// Gets or sets inside of which the dialogue will be placed. The new will replace the current . + /// Gets or sets inside of which the dialogue will be placed. The new will replace the current . /// - public ContentPresenter? ContentPresenter { get; set; } = default; + public ContentPresenter? DialogHost { get; set; } = default; - protected TaskCompletionSource? Tcs; + [Obsolete("ContentPresenter is deprecated. Please use DialogHost instead.")] + public ContentPresenter? ContentPresenter { get; set; } = default; - #region Public methods + protected TaskCompletionSource? Tcs { get; set; } /// /// Shows the dialog /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("WpfAnalyzers.DependencyProperty", "WPF0041:Set mutable dependency properties using SetCurrentValue", Justification = "SetCurrentValue(ContentProperty, ...) will not work")] public async Task ShowAsync(CancellationToken cancellationToken = default) { - if (ContentPresenter is null) + if (DialogHost is null) { - throw new InvalidOperationException("ContentPresenter is not set"); + throw new InvalidOperationException("DialogHost was not set"); } Tcs = new TaskCompletionSource(); @@ -581,7 +530,7 @@ public async Task ShowAsync(CancellationToken cancellationT try { - ContentPresenter.Content = this; + DialogHost.Content = this; result = await Tcs.Task; return result; @@ -593,7 +542,7 @@ public async Task ShowAsync(CancellationToken cancellationT #else tokenRegistration.Dispose(); #endif - ContentPresenter.Content = null; + DialogHost.Content = null; OnClosed(result); } } @@ -603,7 +552,7 @@ public async Task ShowAsync(CancellationToken cancellationT /// public virtual void Hide(ContentDialogResult result = ContentDialogResult.None) { - ContentDialogClosingEventArgs closingEventArgs = new ContentDialogClosingEventArgs(ClosingEvent, this) + var closingEventArgs = new ContentDialogClosingEventArgs(ClosingEvent, this) { Result = result }; @@ -611,19 +560,17 @@ public virtual void Hide(ContentDialogResult result = ContentDialogResult.None) RaiseEvent(closingEventArgs); if (!closingEventArgs.Cancel) - Tcs?.TrySetResult(result); + { + _ = Tcs?.TrySetResult(result); + } } - #endregion - - #region Protected methods - /// /// Occurs after ContentPresenter.Content = null /// protected virtual void OnClosed(ContentDialogResult result) { - ContentDialogClosedEventArgs closedEventArgs = new ContentDialogClosedEventArgs(ClosedEvent, this) + var closedEventArgs = new ContentDialogClosedEventArgs(ClosedEvent, this) { Result = result }; @@ -632,12 +579,12 @@ protected virtual void OnClosed(ContentDialogResult result) } /// - /// Occurs after the is clicked + /// Invoked when a is clicked. /// - /// + /// The button that was clicked. protected virtual void OnButtonClick(ContentDialogButton button) { - ContentDialogButtonClickEventArgs buttonClickEventArgs = new ContentDialogButtonClickEventArgs( + var buttonClickEventArgs = new ContentDialogButtonClickEventArgs( ButtonClickedEvent, this ) @@ -657,10 +604,6 @@ protected virtual void OnButtonClick(ContentDialogButton button) Hide(result); } - #endregion - - #region Base methods - protected override Size MeasureOverride(Size availableSize) { var rootElement = (UIElement)GetVisualChild(0)!; @@ -670,8 +613,8 @@ protected override Size MeasureOverride(Size availableSize) Size newSize = GetNewDialogSize(desiredSize); - DialogHeight = newSize.Height; - DialogWidth = newSize.Width; + SetCurrentValue(DialogHeightProperty, newSize.Height); + SetCurrentValue(DialogWidthProperty, newSize.Width); ResizeWidth(rootElement); ResizeHeight(rootElement); @@ -684,15 +627,11 @@ protected override Size MeasureOverride(Size availableSize) /// protected virtual void OnLoaded() { - Focus(); + _ = Focus(); RaiseEvent(new RoutedEventArgs(OpenedEvent)); } - #endregion - - #region Resize private methods - private Size GetNewDialogSize(Size desiredSize) { var paddingWidth = Padding.Left + Padding.Right; @@ -710,36 +649,38 @@ private Size GetNewDialogSize(Size desiredSize) private void ResizeWidth(UIElement element) { if (DialogWidth <= DialogMaxWidth) + { return; + } - DialogWidth = DialogMaxWidth; + SetCurrentValue(DialogWidthProperty, DialogMaxWidth); element.UpdateLayout(); - DialogHeight = element.DesiredSize.Height; + SetCurrentValue(DialogHeightProperty, element.DesiredSize.Height); if (DialogHeight > DialogMaxHeight) { - DialogMaxHeight = DialogHeight; - //Debug.WriteLine($"DEBUG | {GetType()} | WARNING | DialogHeight > DialogMaxHeight after resizing width!"); + SetCurrentValue(DialogMaxHeightProperty, DialogHeight); + /*Debug.WriteLine($"DEBUG | {GetType()} | WARNING | DialogHeight > DialogMaxHeight after resizing width!");*/ } } private void ResizeHeight(UIElement element) { if (DialogHeight <= DialogMaxHeight) + { return; + } - DialogHeight = DialogMaxHeight; + SetCurrentValue(DialogHeightProperty, DialogMaxHeight); element.UpdateLayout(); - DialogWidth = element.DesiredSize.Width; + SetCurrentValue(DialogWidthProperty, element.DesiredSize.Width); if (DialogWidth > DialogMaxWidth) { - DialogMaxWidth = DialogWidth; - //Debug.WriteLine($"DEBUG | {GetType()} | WARNING | DialogWidth > DialogMaxWidth after resizing height!"); + SetCurrentValue(DialogMaxWidthProperty, DialogWidth); + /*Debug.WriteLine($"DEBUG | {GetType()} | WARNING | DialogWidth > DialogMaxWidth after resizing height!");*/ } } - - #endregion } diff --git a/src/Wpf.Ui/Controls/ContentDialog/ContentDialogEventArgs.cs b/src/Wpf.Ui/Controls/ContentDialog/ContentDialogEventArgs.cs deleted file mode 100644 index e58903c99..000000000 --- a/src/Wpf.Ui/Controls/ContentDialog/ContentDialogEventArgs.cs +++ /dev/null @@ -1,32 +0,0 @@ -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. -// Copyright (C) Leszek Pomianowski and WPF UI Contributors. -// All Rights Reserved. - -// ReSharper disable once CheckNamespace -namespace Wpf.Ui.Controls; - -public class ContentDialogClosingEventArgs : RoutedEventArgs -{ - public ContentDialogClosingEventArgs(RoutedEvent routedEvent, object source) - : base(routedEvent, source) { } - - public required ContentDialogResult Result { get; init; } - public bool Cancel { get; set; } -} - -public class ContentDialogClosedEventArgs : RoutedEventArgs -{ - public ContentDialogClosedEventArgs(RoutedEvent routedEvent, object source) - : base(routedEvent, source) { } - - public required ContentDialogResult Result { get; init; } -} - -public class ContentDialogButtonClickEventArgs : RoutedEventArgs -{ - public ContentDialogButtonClickEventArgs(RoutedEvent routedEvent, object source) - : base(routedEvent, source) { } - - public required ContentDialogButton Button { get; init; } -} diff --git a/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogButtonClickEventArgs.cs b/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogButtonClickEventArgs.cs new file mode 100644 index 000000000..9372921d3 --- /dev/null +++ b/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogButtonClickEventArgs.cs @@ -0,0 +1,15 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +// ReSharper disable once CheckNamespace +namespace Wpf.Ui.Controls; + +public class ContentDialogButtonClickEventArgs : RoutedEventArgs +{ + public ContentDialogButtonClickEventArgs(RoutedEvent routedEvent, object source) + : base(routedEvent, source) { } + + public required ContentDialogButton Button { get; init; } +} diff --git a/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogClosedEventArgs.cs b/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogClosedEventArgs.cs new file mode 100644 index 000000000..88cb3f243 --- /dev/null +++ b/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogClosedEventArgs.cs @@ -0,0 +1,15 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +// ReSharper disable once CheckNamespace +namespace Wpf.Ui.Controls; + +public class ContentDialogClosedEventArgs : RoutedEventArgs +{ + public ContentDialogClosedEventArgs(RoutedEvent routedEvent, object source) + : base(routedEvent, source) { } + + public required ContentDialogResult Result { get; init; } +} diff --git a/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogClosingEventArgs.cs b/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogClosingEventArgs.cs new file mode 100644 index 000000000..7ab462f0a --- /dev/null +++ b/src/Wpf.Ui/Controls/ContentDialog/EventArgs/ContentDialogClosingEventArgs.cs @@ -0,0 +1,17 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +// ReSharper disable once CheckNamespace +namespace Wpf.Ui.Controls; + +public class ContentDialogClosingEventArgs : RoutedEventArgs +{ + public ContentDialogClosingEventArgs(RoutedEvent routedEvent, object source) + : base(routedEvent, source) { } + + public required ContentDialogResult Result { get; init; } + + public bool Cancel { get; set; } +} diff --git a/src/Wpf.Ui/Controls/ContextMenu/ContextMenu.xaml b/src/Wpf.Ui/Controls/ContextMenu/ContextMenu.xaml index 6dec26662..d627afdcb 100644 --- a/src/Wpf.Ui/Controls/ContextMenu/ContextMenu.xaml +++ b/src/Wpf.Ui/Controls/ContextMenu/ContextMenu.xaml @@ -6,10 +6,8 @@ --> + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">