support for sync with system theme

This commit is contained in:
NaBian committed 2021-05-30 14:50:38 +08:00
1 parent d997aee5f7
commit 3da5662a90
10 files changed
+111 -46

No files matched your search

@@ -11752,7 +11752,7 @@
<Setter Property="Focusable" Value="False" />
<Setter Property="MinHeight" Value="60" />
<Setter Property="Width" Value="320" />
<Setter Property="Margin" Value="10,0,0,10" />
<Setter Property="Margin" Value="10,10,10,0" />
<Setter Property="MaxWidth" Value="320" />
<Setter Property="hc:BorderElement.CornerRadius" Value="8" />
<Setter Property="Background" Value="{DynamicResource ThirdlyRegionBrush}" />
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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)
@@ -372,6 +372,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\ScreenHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\SecurityHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\SingleOpenHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\SystemHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\TextHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\TokenizerHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\TouchDragMoveWindowHelper.cs" />
+72 -30
View File
@@ -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<Theme>();
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<Theme>();
if (!themes.Any())
{
element.Resources.MergedDictionaries.Add(new Theme
{
Skin = skin
});
}
else
{
foreach (var subResource in element.Resources.MergedDictionaries.OfType<Theme>())
{
subResource.Skin = skin;
}
}
}
Skin = skin
});
}
}
private static void GetAllThemes(ResourceDictionary resourceDictionary, ref List<Theme> 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);
@@ -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")
};
}
}
@@ -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";
}
}
}