mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
[fxcop] Settings UI library (part 2) (#7257)
* Suppress warnings for read-only collection properties (see code comments) * Call ConfigureAwait on tasks * Add CultureInfo and StringComparison policy for certain string operations * Add checks and exceptions for null arguments to public methods * Rename RaisePropertyChanged to NotifyPropertyChanged * Suppress CA1000 warning on SettingsRepository class * Implement Disposable pattern in HotkeySettingsControlHook * Modify null argument handling in KeyboardManagerViewModel::CombineShortcutLists
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
@@ -24,7 +25,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
|
||||
public bool Compare(AppSpecificKeysDataModel arg)
|
||||
{
|
||||
return OriginalKeys.Equals(arg.OriginalKeys) && NewRemapKeys.Equals(arg.NewRemapKeys) && TargetApp.Equals(arg.TargetApp);
|
||||
if (arg == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(arg));
|
||||
}
|
||||
|
||||
// Using Ordinal comparison for internal text
|
||||
return OriginalKeys.Equals(arg.OriginalKeys, StringComparison.Ordinal) &&
|
||||
NewRemapKeys.Equals(arg.NewRemapKeys, StringComparison.Ordinal) &&
|
||||
TargetApp.Equals(arg.TargetApp, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
|
||||
@@ -30,6 +31,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
WriteIndented = true,
|
||||
};
|
||||
|
||||
if (settingsUtils == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsUtils));
|
||||
}
|
||||
|
||||
settingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), ModuleName);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.CustomAction
|
||||
{
|
||||
PropertyNamingPolicy = new CustomNamePolicy((propertyName) =>
|
||||
{
|
||||
return propertyName.Equals("ModuleAction") ? moduleName : propertyName;
|
||||
// Using Ordinal as this is an internal property name
|
||||
return propertyName.Equals("ModuleAction", System.StringComparison.Ordinal) ? moduleName : propertyName;
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
|
||||
public delegate bool FilterAccessibleKeyboardEvents(int key, UIntPtr extraInfo);
|
||||
|
||||
public class HotkeySettingsControlHook
|
||||
public class HotkeySettingsControlHook : IDisposable
|
||||
{
|
||||
private const int WmKeyDown = 0x100;
|
||||
private const int WmKeyUp = 0x101;
|
||||
@@ -24,6 +24,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
private KeyEvent _keyDown;
|
||||
private KeyEvent _keyUp;
|
||||
private IsActive _isActive;
|
||||
private bool disposedValue;
|
||||
|
||||
private FilterAccessibleKeyboardEvents _filterKeyboardEvent;
|
||||
|
||||
@@ -62,10 +63,24 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
return _filterKeyboardEvent(ev.key, (UIntPtr)ev.dwExtraInfo);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// Dispose the KeyboardHook object to terminate the hook threads
|
||||
_hook.Dispose();
|
||||
}
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Dispose the KeyboardHook object to terminate the hook threads
|
||||
_hook.Dispose();
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
@@ -222,6 +223,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
|
||||
public void Update(ImageSize modifiedSize)
|
||||
{
|
||||
if (modifiedSize == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(modifiedSize));
|
||||
}
|
||||
|
||||
Id = modifiedSize.Id;
|
||||
Name = modifiedSize.Name;
|
||||
Fit = modifiedSize.Fit;
|
||||
|
||||
@@ -10,8 +10,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class ImageResizerSizes
|
||||
{
|
||||
// Suppressing this warning because removing the setter breaks
|
||||
// deserialization with System.Text.Json. This affects the UI display.
|
||||
// See: https://github.com/dotnet/runtime/issues/30258
|
||||
[JsonPropertyName("value")]
|
||||
#pragma warning disable CA2227 // Collection properties should be read only
|
||||
public ObservableCollection<ImageSize> Value { get; set; }
|
||||
#pragma warning restore CA2227 // Collection properties should be read only
|
||||
|
||||
public ImageResizerSizes()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
|
||||
@@ -30,6 +31,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
WriteIndented = true,
|
||||
};
|
||||
|
||||
if (settingsUtils == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsUtils));
|
||||
}
|
||||
|
||||
settingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), ModuleName);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
|
||||
|
||||
@@ -23,6 +24,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
|
||||
public PowerRenameSettings(PowerRenameLocalProperties localProperties)
|
||||
{
|
||||
if (localProperties == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(localProperties));
|
||||
}
|
||||
|
||||
Properties = new PowerRenameProperties();
|
||||
Properties.PersistState.Value = localProperties.PersistState;
|
||||
Properties.MRUEnabled.Value = localProperties.MRUEnabled;
|
||||
|
||||
@@ -10,8 +10,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class RemapKeysDataModel
|
||||
{
|
||||
// Suppressing this warning because removing the setter breaks
|
||||
// deserialization with System.Text.Json. This affects the UI display.
|
||||
// See: https://github.com/dotnet/runtime/issues/30258
|
||||
[JsonPropertyName("inProcess")]
|
||||
#pragma warning disable CA2227 // Collection properties should be read only
|
||||
public List<KeysDataModel> InProcessRemapKeys { get; set; }
|
||||
#pragma warning restore CA2227 // Collection properties should be read only
|
||||
|
||||
public RemapKeysDataModel()
|
||||
{
|
||||
|
||||
@@ -20,7 +20,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
|
||||
private T settingsConfig;
|
||||
|
||||
// Suppressing the warning as this is a singleton class and this method is
|
||||
// necessarily static
|
||||
#pragma warning disable CA1000 // Do not declare static members on generic types
|
||||
public static SettingsRepository<T> GetInstance(ISettingsUtils settingsUtils)
|
||||
#pragma warning restore CA1000 // Do not declare static members on generic types
|
||||
{
|
||||
// To ensure that only one instance of Settings Repository is created in a multi-threaded environment.
|
||||
lock (_SettingsRepoLock)
|
||||
|
||||
@@ -10,11 +10,18 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public class ShortcutsKeyDataModel
|
||||
{
|
||||
// Suppressing these warnings because removing the setter breaks
|
||||
// deserialization with System.Text.Json. This affects the UI display.
|
||||
// See: https://github.com/dotnet/runtime/issues/30258
|
||||
[JsonPropertyName("global")]
|
||||
#pragma warning disable CA2227 // Collection properties should be read only
|
||||
public List<KeysDataModel> GlobalRemapShortcuts { get; set; }
|
||||
#pragma warning restore CA2227 // Collection properties should be read only
|
||||
|
||||
[JsonPropertyName("appSpecific")]
|
||||
#pragma warning disable CA2227 // Collection properties should be read only
|
||||
public List<AppSpecificKeysDataModel> AppSpecificRemapShortcuts { get; set; }
|
||||
#pragma warning restore CA2227 // Collection properties should be read only
|
||||
|
||||
public ShortcutsKeyDataModel()
|
||||
{
|
||||
|
||||
@@ -92,6 +92,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities
|
||||
{
|
||||
// Split up the version strings into int[]
|
||||
// Example: v10.0.2 -> {10, 0, 2};
|
||||
if (version1 == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(version1));
|
||||
}
|
||||
else if (version2 == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(version2));
|
||||
}
|
||||
|
||||
var v1 = version1.Substring(1).Split('.').Select(int.Parse).ToArray();
|
||||
var v2 = version2.Substring(1).Split('.').Select(int.Parse).ToArray();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
|
||||
@@ -24,6 +25,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
public ColorPickerViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc)
|
||||
{
|
||||
// Obtain the general PowerToy settings configurations
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
|
||||
@@ -121,8 +127,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
|
||||
private void NotifySettingsChanged()
|
||||
{
|
||||
// Using InvariantCulture as this is an IPC message
|
||||
SendConfigMSG(
|
||||
string.Format("{{ \"powertoys\": {{ \"{0}\": {1} }} }}", ColorPickerSettings.ModuleName, JsonSerializer.Serialize(_colorPickerSettings)));
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
|
||||
ColorPickerSettings.ModuleName,
|
||||
JsonSerializer.Serialize(_colorPickerSettings)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
|
||||
@@ -28,10 +29,20 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
public FancyZonesViewModel(ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FancyZonesSettings> moduleSettingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")
|
||||
{
|
||||
// To obtain the general settings configurations of PowerToys Settings.
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
settingsConfigFileFolder = configFileSubfolder;
|
||||
|
||||
// To obtain the settings configurations of Fancy zones.
|
||||
if (moduleSettingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(moduleSettingsRepository));
|
||||
}
|
||||
|
||||
Settings = moduleSettingsRepository.SettingsConfig;
|
||||
|
||||
LaunchEditorEventHandler = new ButtonClickCommand(LaunchEditor);
|
||||
@@ -137,7 +148,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_shiftDrag = value;
|
||||
Settings.Properties.FancyzonesShiftDrag.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +166,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_mouseSwitch = value;
|
||||
Settings.Properties.FancyzonesMouseSwitch.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,7 +189,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_overrideSnapHotkeys = value;
|
||||
Settings.Properties.FancyzonesOverrideSnapHotkeys.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled));
|
||||
}
|
||||
}
|
||||
@@ -197,7 +208,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_moveWindowsAcrossMonitors = value;
|
||||
Settings.Properties.FancyzonesMoveWindowsAcrossMonitors.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +226,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_moveWindowsBasedOnPosition = value;
|
||||
Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,7 +244,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_displayChangemoveWindows = value;
|
||||
Settings.Properties.FancyzonesDisplayChangeMoveWindows.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,7 +262,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_zoneSetChangeMoveWindows = value;
|
||||
Settings.Properties.FancyzonesZoneSetChangeMoveWindows.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,7 +280,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_appLastZoneMoveWindows = value;
|
||||
Settings.Properties.FancyzonesAppLastZoneMoveWindows.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +298,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_openWindowOnActiveMonitor = value;
|
||||
Settings.Properties.FancyzonesOpenWindowOnActiveMonitor.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,7 +316,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_restoreSize = value;
|
||||
Settings.Properties.FancyzonesRestoreSize.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -323,7 +334,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_useCursorPosEditorStartupScreen = value;
|
||||
Settings.Properties.UseCursorposEditorStartupscreen.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,7 +352,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_showOnAllMonitors = value;
|
||||
Settings.Properties.FancyzonesShowOnAllMonitors.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,7 +370,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_spanZonesAcrossMonitors = value;
|
||||
Settings.Properties.FancyzonesSpanZonesAcrossMonitors.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,11 +388,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_makeDraggedWindowTransparent = value;
|
||||
Settings.Properties.FancyzonesMakeDraggedWindowTransparent.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For the following setters we use OrdinalIgnoreCase string comparison since
|
||||
// we expect value to be a hex code.
|
||||
public string ZoneHighlightColor
|
||||
{
|
||||
get
|
||||
@@ -391,12 +404,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
|
||||
set
|
||||
{
|
||||
value = ToRGBHex(value);
|
||||
if (!value.Equals(_zoneHighlightColor))
|
||||
// The fallback value is based on ToRGBHex's behavior, which returns
|
||||
// #FFFFFF if any exceptions are encountered, e.g. from passing in a null value.
|
||||
// This extra handling is added here to deal with FxCop warnings.
|
||||
value = (value != null) ? ToRGBHex(value) : "#FFFFFF";
|
||||
if (!value.Equals(_zoneHighlightColor, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_zoneHighlightColor = value;
|
||||
Settings.Properties.FancyzonesZoneHighlightColor.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -410,12 +426,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
|
||||
set
|
||||
{
|
||||
value = ToRGBHex(value);
|
||||
// The fallback value is based on ToRGBHex's behavior, which returns
|
||||
// #FFFFFF if any exceptions are encountered, e.g. from passing in a null value.
|
||||
// This extra handling is added here to deal with FxCop warnings.
|
||||
value = (value != null) ? ToRGBHex(value) : "#FFFFFF";
|
||||
if (!value.Equals(_zoneBorderColor, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_zoneBorderColor = value;
|
||||
Settings.Properties.FancyzonesBorderColor.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,12 +448,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
|
||||
set
|
||||
{
|
||||
value = ToRGBHex(value);
|
||||
if (!value.Equals(_zoneInActiveColor))
|
||||
// The fallback value is based on ToRGBHex's behavior, which returns
|
||||
// #FFFFFF if any exceptions are encountered, e.g. from passing in a null value.
|
||||
// This extra handling is added here to deal with FxCop warnings.
|
||||
value = (value != null) ? ToRGBHex(value) : "#FFFFFF";
|
||||
if (!value.Equals(_zoneInActiveColor, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_zoneInActiveColor = value;
|
||||
Settings.Properties.FancyzonesInActiveColor.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,7 +474,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_highlightOpacity = value;
|
||||
Settings.Properties.FancyzonesHighlightOpacity.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,7 +490,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
if (value != _editorHotkey)
|
||||
{
|
||||
if (value.IsEmpty())
|
||||
if (value == null || value.IsEmpty())
|
||||
{
|
||||
_editorHotkey = FZConfigProperties.DefaultHotkeyValue;
|
||||
}
|
||||
@@ -478,7 +500,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
}
|
||||
|
||||
Settings.Properties.FancyzonesEditorHotkey.Value = _editorHotkey;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,7 +518,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_excludedApps = value;
|
||||
Settings.Properties.FancyzonesExcludedApps.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -507,7 +529,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
SendConfigMSG("{\"action\":{\"FancyZones\":{\"action_name\":\"ToggledFZEditor\", \"value\":\"\"}}}");
|
||||
}
|
||||
|
||||
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
||||
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
OnPropertyChanged(propertyName);
|
||||
if (SendConfigMSG != null)
|
||||
@@ -522,9 +544,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
int argb = int.Parse(color.Replace("#", string.Empty), System.Globalization.NumberStyles.HexNumber);
|
||||
// Using InvariantCulture as these are expected to be hex codes.
|
||||
int argb = int.Parse(
|
||||
color.Replace("#", string.Empty),
|
||||
System.Globalization.NumberStyles.HexNumber,
|
||||
CultureInfo.InvariantCulture);
|
||||
Color clr = Color.FromArgb(argb);
|
||||
return "#" + clr.R.ToString("X2") + clr.G.ToString("X2") + clr.B.ToString("X2");
|
||||
return "#" + clr.R.ToString("X2", CultureInfo.InvariantCulture) +
|
||||
clr.G.ToString("X2", CultureInfo.InvariantCulture) +
|
||||
clr.B.ToString("X2", CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Interface;
|
||||
@@ -39,6 +40,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
RestartElevatedButtonEventHandler = new ButtonClickCommand(RestartElevated);
|
||||
|
||||
// To obtain the general settings configuration of PowerToys if it exists, else to create a new file and return the default configurations.
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
// set the callback functions value to hangle outgoing IPC message.
|
||||
@@ -48,20 +54,25 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
|
||||
// set the callback function value to update the UI theme.
|
||||
UpdateUIThemeCallBack = updateTheme;
|
||||
UpdateUIThemeCallBack(GeneralSettingsConfig.Theme.ToLower());
|
||||
|
||||
UpdateUIThemeCallBack(GeneralSettingsConfig.Theme);
|
||||
|
||||
// Update Settings file folder:
|
||||
_settingsConfigFileFolder = configFileSubfolder;
|
||||
|
||||
switch (GeneralSettingsConfig.Theme.ToLower())
|
||||
// Using Invariant here as these are internal strings and fxcop
|
||||
// expects strings to be normalized to uppercase. While the theme names
|
||||
// are represented in lowercase everywhere else, we'll use uppercase
|
||||
// normalization for switch statements
|
||||
switch (GeneralSettingsConfig.Theme.ToUpperInvariant())
|
||||
{
|
||||
case "light":
|
||||
case "LIGHT":
|
||||
_isLightThemeRadioButtonChecked = true;
|
||||
break;
|
||||
case "dark":
|
||||
case "DARK":
|
||||
_isDarkThemeRadioButtonChecked = true;
|
||||
break;
|
||||
case "system":
|
||||
case "SYSTEM":
|
||||
_isSystemThemeRadioButtonChecked = true;
|
||||
break;
|
||||
}
|
||||
@@ -102,7 +113,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
if (_packaged != value)
|
||||
{
|
||||
_packaged = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +132,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_startup = value;
|
||||
GeneralSettingsConfig.Startup = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,7 +204,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_runElevated = value;
|
||||
GeneralSettingsConfig.RunElevated = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,7 +231,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_autoDownloadUpdates = value;
|
||||
GeneralSettingsConfig.AutoDownloadUpdates = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,7 +257,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
}
|
||||
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,7 +283,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
}
|
||||
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,7 +309,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
}
|
||||
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,12 +340,12 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
if (_latestAvailableVersion != value)
|
||||
{
|
||||
_latestAvailableVersion = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
||||
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
// Notify UI of property change
|
||||
OnPropertyChanged(propertyName);
|
||||
|
||||
@@ -28,6 +28,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
|
||||
|
||||
// To obtain the general settings configurations of PowerToys.
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
try
|
||||
@@ -92,13 +97,18 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable CA2227 // Collection properties should be read only
|
||||
public ObservableCollection<ImageSize> Sizes
|
||||
#pragma warning restore CA2227 // Collection properties should be read only
|
||||
{
|
||||
get
|
||||
{
|
||||
return _advancedSizes;
|
||||
}
|
||||
|
||||
// FxCop demands collection properties to be read-only, but this
|
||||
// setter is used in autogenerated files (ImageResizerPage.g.cs)
|
||||
// and replacing the setter with its own method will break the file
|
||||
set
|
||||
{
|
||||
SavesImageSizes(value);
|
||||
|
||||
@@ -43,6 +43,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
|
||||
public KeyboardManagerViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, Func<List<KeysDataModel>, int> filterRemapKeysList)
|
||||
{
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
// set the callback functions value to hangle outgoing IPC message.
|
||||
@@ -107,7 +112,22 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
|
||||
public static List<AppSpecificKeysDataModel> CombineShortcutLists(List<KeysDataModel> globalShortcutList, List<AppSpecificKeysDataModel> appSpecificShortcutList)
|
||||
{
|
||||
return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).Concat(appSpecificShortcutList).ToList();
|
||||
if (globalShortcutList == null && appSpecificShortcutList == null)
|
||||
{
|
||||
return new List<AppSpecificKeysDataModel>();
|
||||
}
|
||||
else if (globalShortcutList == null)
|
||||
{
|
||||
return appSpecificShortcutList;
|
||||
}
|
||||
else if (appSpecificShortcutList == null)
|
||||
{
|
||||
return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).Concat(appSpecificShortcutList).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public List<AppSpecificKeysDataModel> RemapShortcuts
|
||||
@@ -129,28 +149,31 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
|
||||
public ICommand EditShortcutCommand => _editShortcutCommand ?? (_editShortcutCommand = new RelayCommand(OnEditShortcut));
|
||||
|
||||
// Note: FxCop suggests calling ConfigureAwait() for the following methods,
|
||||
// and calling ConfigureAwait(true) has the same behavior as not explicitly
|
||||
// calling it (continuations are scheduled on the task-creating thread)
|
||||
private async void OnRemapKeyboard()
|
||||
{
|
||||
await Task.Run(() => OnRemapKeyboardBackground());
|
||||
await Task.Run(() => OnRemapKeyboardBackground()).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
private async void OnEditShortcut()
|
||||
{
|
||||
await Task.Run(() => OnEditShortcutBackground());
|
||||
await Task.Run(() => OnEditShortcutBackground()).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
private async Task OnRemapKeyboardBackground()
|
||||
{
|
||||
Helper.AllowRunnerToForeground();
|
||||
SendConfigMSG(Helper.GetSerializedCustomAction(PowerToyName, RemapKeyboardActionName, RemapKeyboardActionValue));
|
||||
await Task.CompletedTask;
|
||||
await Task.CompletedTask.ConfigureAwait(true);
|
||||
}
|
||||
|
||||
private async Task OnEditShortcutBackground()
|
||||
{
|
||||
Helper.AllowRunnerToForeground();
|
||||
SendConfigMSG(Helper.GetSerializedCustomAction(PowerToyName, EditShortcutActionName, EditShortcutActionValue));
|
||||
await Task.CompletedTask;
|
||||
await Task.CompletedTask.ConfigureAwait(true);
|
||||
}
|
||||
|
||||
public void NotifyFileChanged()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
|
||||
@@ -29,6 +30,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
|
||||
|
||||
// To obtain the general Settings configurations of PowerToys
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
// set the callback functions value to hangle outgoing IPC message.
|
||||
@@ -36,8 +42,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
callback = (PowerLauncherSettings settings) =>
|
||||
{
|
||||
// Propagate changes to Power Launcher through IPC
|
||||
// Using InvariantCulture as this is an IPC message
|
||||
SendConfigMSG(
|
||||
string.Format("{{ \"powertoys\": {{ \"{0}\": {1} }} }}", PowerLauncherSettings.ModuleName, JsonSerializer.Serialize(settings)));
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
|
||||
PowerLauncherSettings.ModuleName,
|
||||
JsonSerializer.Serialize(settings)));
|
||||
};
|
||||
|
||||
if (_settingsUtils.SettingsExists(PowerLauncherSettings.ModuleName))
|
||||
|
||||
@@ -27,10 +27,20 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
_settingsConfigFileFolder = configFileSubfolder;
|
||||
|
||||
// To obtain the general Settings configurations of PowerToys
|
||||
if (generalSettingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(generalSettingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = generalSettingsRepository.SettingsConfig;
|
||||
|
||||
// To obtain the PowerPreview settings if it exists.
|
||||
// If the file does not exist, to create a new one and return the default settings configurations.
|
||||
if (moduleSettingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(moduleSettingsRepository));
|
||||
}
|
||||
|
||||
Settings = moduleSettingsRepository.SettingsConfig;
|
||||
|
||||
// set the callback functions value to hangle outgoing IPC message.
|
||||
|
||||
@@ -29,6 +29,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
_settingsConfigFileFolder = configFileSubfolder;
|
||||
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
|
||||
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
try
|
||||
|
||||
@@ -27,10 +27,20 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
_settingsConfigFileFolder = configFileSubfolder;
|
||||
|
||||
// To obtain the general PowerToys settings.
|
||||
if (settingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
// To obtain the shortcut guide settings, if the file exists.
|
||||
// If not, to create a file with the default settings and to return the default configurations.
|
||||
if (moduleSettingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(moduleSettingsRepository));
|
||||
}
|
||||
|
||||
Settings = moduleSettingsRepository.SettingsConfig;
|
||||
|
||||
// set the callback functions value to hangle outgoing IPC message.
|
||||
@@ -102,7 +112,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
// set theme to dark.
|
||||
Settings.Properties.Theme.Value = "dark";
|
||||
_themeIndex = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
|
||||
if (value == 1)
|
||||
@@ -110,7 +120,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
// set theme to light.
|
||||
Settings.Properties.Theme.Value = "light";
|
||||
_themeIndex = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
|
||||
if (value == 2)
|
||||
@@ -118,7 +128,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
// set theme to system default.
|
||||
Settings.Properties.Theme.Value = "system";
|
||||
_themeIndex = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,7 +147,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_pressTime = value;
|
||||
Settings.Properties.PressTime.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +165,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
_opacity = value;
|
||||
Settings.Properties.OverlayOpacity.Value = value;
|
||||
RaisePropertyChanged();
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +175,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
return _settingsConfigFileFolder + "\\" + ModuleName;
|
||||
}
|
||||
|
||||
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
||||
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
OnPropertyChanged(propertyName);
|
||||
SndShortcutGuideSettings outsettings = new SndShortcutGuideSettings(Settings);
|
||||
|
||||
@@ -41,6 +41,69 @@ namespace ViewModelTests
|
||||
Assert.AreEqual(expectedResult.Count, result.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CombineShortcutListsShouldReturnEmptyListWhenBothArgumentsAreNull()
|
||||
{
|
||||
// act
|
||||
var result = KeyboardManagerViewModel.CombineShortcutLists(null, null);
|
||||
|
||||
// Assert
|
||||
var expectedResult = new List<AppSpecificKeysDataModel>();
|
||||
|
||||
Assert.AreEqual(expectedResult.Count, result.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CombineShortcutListsShouldReturnListWithOneAppSpecificEntryWhenFirstArgumentIsNullAndSecondArgumentHasOneEntry()
|
||||
{
|
||||
// arrange
|
||||
var secondList = new List<AppSpecificKeysDataModel>();
|
||||
var entry = new AppSpecificKeysDataModel();
|
||||
entry.OriginalKeys = "17;65";
|
||||
entry.NewRemapKeys = "17;86";
|
||||
entry.TargetApp = "msedge";
|
||||
secondList.Add(entry);
|
||||
|
||||
// act
|
||||
var result = KeyboardManagerViewModel.CombineShortcutLists(null, secondList);
|
||||
|
||||
// Assert
|
||||
var expectedResult = new List<AppSpecificKeysDataModel>();
|
||||
var expectedEntry = new AppSpecificKeysDataModel();
|
||||
expectedEntry.OriginalKeys = entry.OriginalKeys;
|
||||
expectedEntry.NewRemapKeys = entry.NewRemapKeys;
|
||||
expectedEntry.TargetApp = entry.TargetApp;
|
||||
expectedResult.Add(expectedEntry);
|
||||
|
||||
Assert.AreEqual(expectedResult.Count, result.Count);
|
||||
Assert.IsTrue(expectedResult[0].Compare(result[0]));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CombineShortcutListsShouldReturnListWithOneAllAppsEntryWhenFirstArgumentHasOneEntryAndSecondArgumentIsNull()
|
||||
{
|
||||
// arrange
|
||||
var firstList = new List<KeysDataModel>();
|
||||
var entry = new KeysDataModel();
|
||||
entry.OriginalKeys = "17;65";
|
||||
entry.NewRemapKeys = "17;86";
|
||||
firstList.Add(entry);
|
||||
|
||||
// act
|
||||
var result = KeyboardManagerViewModel.CombineShortcutLists(firstList, null);
|
||||
|
||||
// Assert
|
||||
var expectedResult = new List<AppSpecificKeysDataModel>();
|
||||
var expectedEntry = new AppSpecificKeysDataModel();
|
||||
expectedEntry.OriginalKeys = entry.OriginalKeys;
|
||||
expectedEntry.NewRemapKeys = entry.NewRemapKeys;
|
||||
expectedEntry.TargetApp = "All Apps";
|
||||
expectedResult.Add(expectedEntry);
|
||||
|
||||
Assert.AreEqual(expectedResult.Count, result.Count);
|
||||
Assert.IsTrue(expectedResult[0].Compare(result[0]));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CombineShortcutListsShouldReturnListWithOneAllAppsEntryWhenFirstArgumentHasOneEntryAndSecondArgumentIsEmpty()
|
||||
{
|
||||
|
||||
@@ -79,15 +79,15 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
|
||||
public int UpdateUIThemeMethod(string themeName)
|
||||
{
|
||||
switch (themeName)
|
||||
switch (themeName.ToUpperInvariant())
|
||||
{
|
||||
case "light":
|
||||
case "LIGHT":
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Light;
|
||||
break;
|
||||
case "dark":
|
||||
case "DARK":
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Dark;
|
||||
break;
|
||||
case "system":
|
||||
case "SYSTEM":
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Default;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user