diff --git a/src/Net_40/HandyControl_Net_40/Themes/Theme.xaml b/src/Net_40/HandyControl_Net_40/Themes/Theme.xaml index 25ce5453..79b31966 100644 --- a/src/Net_40/HandyControl_Net_40/Themes/Theme.xaml +++ b/src/Net_40/HandyControl_Net_40/Themes/Theme.xaml @@ -11752,7 +11752,7 @@ - + diff --git a/src/Shared/HandyControl_Shared/Controls/Attach/DataGridAttach.cs b/src/Shared/HandyControl_Shared/Controls/Attach/DataGridAttach.cs index c46040a3..1e20f87b 100644 --- a/src/Shared/HandyControl_Shared/Controls/Attach/DataGridAttach.cs +++ b/src/Shared/HandyControl_Shared/Controls/Attach/DataGridAttach.cs @@ -337,7 +337,7 @@ namespace HandyControl.Controls } public static void SetCanUnselectAllWithBlankArea(DependencyObject element, bool value) - => element.SetValue(CanUnselectAllWithBlankAreaProperty, value); + => element.SetValue(CanUnselectAllWithBlankAreaProperty, ValueBoxes.BooleanBox(value)); public static bool GetCanUnselectAllWithBlankArea(DependencyObject element) => (bool) element.GetValue(CanUnselectAllWithBlankAreaProperty); diff --git a/src/Shared/HandyControl_Shared/Controls/Attach/DropDownElement.cs b/src/Shared/HandyControl_Shared/Controls/Attach/DropDownElement.cs index 3ac8d63b..7a8561f2 100644 --- a/src/Shared/HandyControl_Shared/Controls/Attach/DropDownElement.cs +++ b/src/Shared/HandyControl_Shared/Controls/Attach/DropDownElement.cs @@ -20,7 +20,7 @@ namespace HandyControl.Controls new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.Inherits)); public static void SetAutoWidth(DependencyObject element, bool value) - => element.SetValue(AutoWidthProperty, value); + => element.SetValue(AutoWidthProperty, ValueBoxes.BooleanBox(value)); public static bool GetAutoWidth(DependencyObject element) => (bool) element.GetValue(AutoWidthProperty); diff --git a/src/Shared/HandyControl_Shared/Controls/Attach/WindowAttach.cs b/src/Shared/HandyControl_Shared/Controls/Attach/WindowAttach.cs index f6b2e193..14441d40 100644 --- a/src/Shared/HandyControl_Shared/Controls/Attach/WindowAttach.cs +++ b/src/Shared/HandyControl_Shared/Controls/Attach/WindowAttach.cs @@ -141,7 +141,7 @@ namespace HandyControl.Controls } public static void SetHideWhenClosing(DependencyObject element, bool value) - => element.SetValue(HideWhenClosingProperty, value); + => element.SetValue(HideWhenClosingProperty, ValueBoxes.BooleanBox(value)); public static bool GetHideWhenClosing(DependencyObject element) => (bool) element.GetValue(HideWhenClosingProperty); diff --git a/src/Shared/HandyControl_Shared/Controls/Other/Empty.cs b/src/Shared/HandyControl_Shared/Controls/Other/Empty.cs index 459a6cc0..e2e05252 100644 --- a/src/Shared/HandyControl_Shared/Controls/Other/Empty.cs +++ b/src/Shared/HandyControl_Shared/Controls/Other/Empty.cs @@ -28,7 +28,7 @@ namespace HandyControl.Controls "ShowEmpty", typeof(bool), typeof(Empty), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.Inherits)); public static void SetShowEmpty(DependencyObject element, bool value) - => element.SetValue(ShowEmptyProperty, value); + => element.SetValue(ShowEmptyProperty, ValueBoxes.BooleanBox(value)); public static bool GetShowEmpty(DependencyObject element) => (bool) element.GetValue(ShowEmptyProperty); diff --git a/src/Shared/HandyControl_Shared/Controls/Window/BlurWindow.cs b/src/Shared/HandyControl_Shared/Controls/Window/BlurWindow.cs index 1eb6fe9d..b68db22e 100644 --- a/src/Shared/HandyControl_Shared/Controls/Window/BlurWindow.cs +++ b/src/Shared/HandyControl_Shared/Controls/Window/BlurWindow.cs @@ -2,6 +2,7 @@ using System.Windows.Media; using HandyControl.Data; using HandyControl.Tools; +using HandyControl.Tools.Helper; using HandyControl.Tools.Interop; namespace HandyControl.Controls @@ -14,17 +15,9 @@ namespace HandyControl.Controls EnableBlur(this); } - private static SystemVersionInfo GetSystemVersionInfo() - { - var osv = new InteropValues.RTL_OSVERSIONINFOEX(); - osv.dwOSVersionInfoSize = (uint) Marshal.SizeOf(osv); - InteropMethods.Gdip.RtlGetVersion(out osv); - return new SystemVersionInfo((int) osv.dwMajorVersion, (int) osv.dwMinorVersion, (int) osv.dwBuildNumber); - } - internal static void EnableBlur(Window window) { - var versionInfo = GetSystemVersionInfo(); + var versionInfo = SystemHelper.GetSystemVersionInfo(); if (versionInfo < SystemVersionInfo.Windows10 || versionInfo >= SystemVersionInfo.Windows10_1903) diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 34a1414f..4818b28e 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -372,6 +372,7 @@ + diff --git a/src/Shared/HandyControl_Shared/Themes/Theme.cs b/src/Shared/HandyControl_Shared/Themes/Theme.cs index 17219c41..70f2223f 100644 --- a/src/Shared/HandyControl_Shared/Themes/Theme.cs +++ b/src/Shared/HandyControl_Shared/Themes/Theme.cs @@ -1,8 +1,10 @@ using System; -using System.Linq; +using System.Collections.Generic; using System.Windows; using HandyControl.Data; using HandyControl.Tools; +using HandyControl.Tools.Helper; +using Microsoft.Win32; namespace HandyControl.Themes { @@ -12,14 +14,8 @@ namespace HandyControl.Themes { if (DesignerHelper.IsInDesignMode) { - MergedDictionaries.Add(new() - { - Source = new Uri("pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml") - }); - MergedDictionaries.Add(new() - { - Source = new Uri("pack://application:,,,/HandyControl;component/Themes/Theme.xaml") - }); + MergedDictionaries.Add(ResourceHelper.GetSkin(SkinType.Default)); + MergedDictionaries.Add(ResourceHelper.GetTheme()); } else { @@ -35,6 +31,8 @@ namespace HandyControl.Themes set => _source = value; } + private SkinType _manualSkinType; + private SkinType _skin; public virtual SkinType Skin @@ -54,32 +52,43 @@ namespace HandyControl.Themes private static void OnSkinChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - if (d is FrameworkElement element) + if (d is not FrameworkElement element) { - var skin = (SkinType) e.NewValue; + return; + } - if (element.Resources is Theme resource) + var skin = (SkinType) e.NewValue; + + var themes = new List(); + GetAllThemes(element.Resources, ref themes); + + if (themes.Count > 0) + { + foreach (var theme in themes) { - resource.Skin = skin; + theme.Skin = skin; } - else + } + else + { + element.Resources.MergedDictionaries.Add(new Theme { - var themes = element.Resources.MergedDictionaries.OfType(); - if (!themes.Any()) - { - element.Resources.MergedDictionaries.Add(new Theme - { - Skin = skin - }); - } - else - { - foreach (var subResource in element.Resources.MergedDictionaries.OfType()) - { - subResource.Skin = skin; - } - } - } + Skin = skin + }); + } + } + + private static void GetAllThemes(ResourceDictionary resourceDictionary, ref List themes) + { + if (resourceDictionary is Theme theme) + { + themes.Add(theme); + } + + // we must consider it's MergedDictionaries + foreach (var dictionaryMergedDictionary in resourceDictionary.MergedDictionaries) + { + GetAllThemes(dictionaryMergedDictionary, ref themes); } } @@ -89,6 +98,39 @@ namespace HandyControl.Themes public static SkinType GetSkin(DependencyObject element) => (SkinType) element.GetValue(SkinProperty); + private bool _syncWithSystem; + + public bool SyncWithSystem + { + get => _syncWithSystem; + set + { + _syncWithSystem = value; + + if (value) + { + _manualSkinType = Skin; + SyncWithSystemTheme(); + SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; + } + else + { + SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged; + Skin = _manualSkinType; + } + } + } + + private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + if (e.Category == UserPreferenceCategory.General) + { + SyncWithSystemTheme(); + } + } + + private void SyncWithSystemTheme() => Skin = SystemHelper.DetermineIfInLightThemeMode() ? SkinType.Default : SkinType.Dark; + public string Name { get; set; } public virtual ResourceDictionary GetSkin(SkinType skinType) => ResourceHelper.GetSkin(skinType); diff --git a/src/Shared/HandyControl_Shared/Tools/Helper/ResourceHelper.cs b/src/Shared/HandyControl_Shared/Tools/Helper/ResourceHelper.cs index 6debc387..3eef1295 100644 --- a/src/Shared/HandyControl_Shared/Tools/Helper/ResourceHelper.cs +++ b/src/Shared/HandyControl_Shared/Tools/Helper/ResourceHelper.cs @@ -54,7 +54,7 @@ namespace HandyControl.Tools { try { - var uri = new Uri($"pack://application:,,,/{assembly.GetName().Name};component/{themePath}/Skin{skin.ToString()}.xaml"); + var uri = new Uri($"pack://application:,,,/{assembly.GetName().Name};component/{themePath}/Skin{skin}.xaml"); return new ResourceDictionary { Source = uri @@ -64,7 +64,7 @@ namespace HandyControl.Tools { return new ResourceDictionary { - Source = new Uri($"pack://application:,,,/{assembly.GetName().Name};component/{themePath}/Skin{SkinType.Default.ToString()}.xaml") + Source = new Uri($"pack://application:,,,/{assembly.GetName().Name};component/{themePath}/Skin{SkinType.Default}.xaml") }; } } diff --git a/src/Shared/HandyControl_Shared/Tools/Helper/SystemHelper.cs b/src/Shared/HandyControl_Shared/Tools/Helper/SystemHelper.cs new file mode 100644 index 00000000..a2349722 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Tools/Helper/SystemHelper.cs @@ -0,0 +1,29 @@ +using System.Runtime.InteropServices; +using HandyControl.Data; +using HandyControl.Tools.Interop; +using Microsoft.Win32; + +namespace HandyControl.Tools.Helper +{ + internal class SystemHelper + { + public static SystemVersionInfo GetSystemVersionInfo() + { + var osv = new InteropValues.RTL_OSVERSIONINFOEX(); + osv.dwOSVersionInfoSize = (uint) Marshal.SizeOf(osv); + InteropMethods.Gdip.RtlGetVersion(out osv); + return new SystemVersionInfo((int) osv.dwMajorVersion, (int) osv.dwMinorVersion, (int) osv.dwBuildNumber); + } + + private const string SkinTypeRegistryKeyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; + + private const string SkinTypeRegistryValueName = "AppsUseLightTheme"; + + public static bool DetermineIfInLightThemeMode() + { + var value = Registry.GetValue(SkinTypeRegistryKeyName, SkinTypeRegistryValueName, "0"); + + return value != null && value.ToString() != "0"; + } + } +}