From 14f35d19f776fa50a3eeca9fb52c90e0c857e9a9 Mon Sep 17 00:00:00 2001 From: Matt Cooley Date: Tue, 16 May 2023 09:04:55 -0700 Subject: [PATCH] Use a markup extension instead of x:Uid to load localized strings (#1902) This PR uses XAML markup extensions, ResourceString and ResourceVirtualKey, to load localized resources instead of using x:Uid. I used a script to find all strings corresponding to an x:Uid and substitute them into the XAML, and then manually cleaned up the generated code. This is intended to improve developer productivity. Now, when reading the XAML file, you don't have to cross-reference the resw file to see if a control has a tooltip or an automation name. Decoupling the UI from the string names also makes it easier to change the UI without impacting localization: for example, you can now use the same string in multiple places, or use an existing string on a new UI element. For now, I've avoided making any changes to the resw file to avoid impacting the localization process. --- src/Calculator/App.xaml | 7 +- src/Calculator/Calculator.csproj | 2 + src/Calculator/Utils/ResourceString.cs | 19 ++ src/Calculator/Utils/ResourceVirtualKey.cs | 21 ++ src/Calculator/Views/Calculator.xaml | 77 ++++-- .../CalculatorProgrammerBitFlipPanel.xaml | 11 +- .../CalculatorProgrammerDisplayPanel.xaml | 31 ++- .../Views/CalculatorProgrammerOperators.xaml | 23 +- .../CalculatorProgrammerRadixOperators.xaml | 170 ++++++++---- .../CalculatorScientificAngleButtons.xaml | 18 +- .../Views/CalculatorScientificOperators.xaml | 233 ++++++++++------ .../Views/CalculatorStandardOperators.xaml | 59 ++-- src/Calculator/Views/DateCalculator.xaml | 45 +-- src/Calculator/Views/DelighterUnitStyles.xaml | 2 +- .../GraphingCalculator/EquationInputArea.xaml | 79 +++--- .../EquationStylePanelControl.xaml | 23 +- .../GraphingCalculator.xaml | 41 +-- .../GraphingCalculator/GraphingNumPad.xaml | 261 ++++++++++++------ .../GraphingCalculator/GraphingSettings.xaml | 53 ++-- .../KeyGraphFeaturesPanel.xaml | 18 +- src/Calculator/Views/HistoryList.xaml | 27 +- src/Calculator/Views/MainPage.xaml | 37 +-- src/Calculator/Views/Memory.xaml | 13 +- src/Calculator/Views/MemoryListItem.xaml | 34 ++- src/Calculator/Views/NumberPad.xaml | 45 +-- src/Calculator/Views/Settings.xaml | 39 +-- .../Views/SupplementaryResults.xaml | 6 +- src/Calculator/Views/TitleBar.xaml | 4 +- src/Calculator/Views/UnitConverter.xaml | 26 +- 29 files changed, 888 insertions(+), 536 deletions(-) create mode 100644 src/Calculator/Utils/ResourceString.cs create mode 100644 src/Calculator/Utils/ResourceVirtualKey.cs diff --git a/src/Calculator/App.xaml b/src/Calculator/App.xaml index 2bf5bc2c..e2a61fc1 100644 --- a/src/Calculator/App.xaml +++ b/src/Calculator/App.xaml @@ -8,7 +8,8 @@ xmlns:converters="using:CalculatorApp.Converters" xmlns:local="using:CalculatorApp" xmlns:muxc="using:Microsoft.UI.Xaml.Controls" - xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives"> + xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives" + xmlns:utils="using:CalculatorApp.Utils"> @@ -790,7 +791,6 @@ TextWrapping="NoWrap"/> + + EquationStylePanelControl.xaml diff --git a/src/Calculator/Utils/ResourceString.cs b/src/Calculator/Utils/ResourceString.cs new file mode 100644 index 00000000..274096f3 --- /dev/null +++ b/src/Calculator/Utils/ResourceString.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using CalculatorApp.ViewModel.Common; +using Windows.UI.Xaml.Markup; + +namespace CalculatorApp.Utils +{ + [MarkupExtensionReturnType(ReturnType = typeof(string))] + public sealed class ResourceString : MarkupExtension + { + public string Name { get; set; } + + protected override object ProvideValue() + { + return AppResourceProvider.GetInstance().GetResourceString(this.Name); + } + } +} diff --git a/src/Calculator/Utils/ResourceVirtualKey.cs b/src/Calculator/Utils/ResourceVirtualKey.cs new file mode 100644 index 00000000..3ec38c6e --- /dev/null +++ b/src/Calculator/Utils/ResourceVirtualKey.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using CalculatorApp.ViewModel.Common; +using System; +using Windows.UI.Xaml.Markup; + +namespace CalculatorApp.Utils +{ + [MarkupExtensionReturnType(ReturnType = typeof(MyVirtualKey))] + public sealed class ResourceVirtualKey : MarkupExtension + { + public string Name { get; set; } + + protected override object ProvideValue() + { + var resourceString = AppResourceProvider.GetInstance().GetResourceString(this.Name); + return Enum.Parse(typeof(MyVirtualKey), resourceString); + } + } +} diff --git a/src/Calculator/Views/Calculator.xaml b/src/Calculator/Views/Calculator.xaml index 9045f1c5..b7c3b85a 100644 --- a/src/Calculator/Views/Calculator.xaml +++ b/src/Calculator/Views/Calculator.xaml @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:automation="using:CalculatorApp.ViewModel.Common.Automation" - xmlns:common="using:CalculatorApp.ViewModel.Common" + xmlns:common="using:CalculatorApp.Common" xmlns:contract7Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,7)" xmlns:contract8NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,8)" xmlns:contract8Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,8)" @@ -11,25 +11,27 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:CalculatorApp" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:utils="using:CalculatorApp.Utils" + xmlns:vmcommon="using:CalculatorApp.ViewModel.Common" Loaded="OnLoaded" mc:Ignorable="d"> - + - + - + @@ -73,19 +75,19 @@ - - + AutomationProperties.HeadingLevel="Level1" + Text="{utils:ResourceString Name=KeyGraphFeaturesLabel/Text}"/> @@ -42,18 +44,20 @@ - + Invoked="OnDeleteSwipeInvoked" + Text="{utils:ResourceString Name=DeleteHistorySwipeItem/Text}"/> - - + + Icon="Delete" + Text="{utils:ResourceString Name=DeleteHistoryMenuItem/Text}"/> @@ -133,10 +137,10 @@