From e19114949b32bb567ae2431970ab2f2e32bf8ae7 Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Mon, 11 Oct 2021 14:07:36 -0700 Subject: [PATCH 01/12] Adding ResourceStringExtension --- .../Assets/Strings/en-US/Resources.resw | 126 ++++++++++++++++++ .../Assets/Strings/es-ES/Resources.resw | 126 ++++++++++++++++++ .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 11 ++ .../ResourceString/ResourceString.png | Bin 0 -> 6035 bytes .../ResourceString/ResourceStringPage.xaml | 8 ++ .../ResourceString/ResourceStringPage.xaml.cs | 26 ++++ .../ResourceString/ResourceStringXaml.bind | 50 +++++++ .../SamplePages/XamlOnlyPage.xaml | 2 + .../SamplePages/samples.json | 13 +- .../Markup/ResourceStringExtension.cs | 51 +++++++ Windows Community Toolkit.sln | 3 + 11 files changed, 414 insertions(+), 2 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/Assets/Strings/en-US/Resources.resw create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/Assets/Strings/es-ES/Resources.resw create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceString.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringPage.xaml create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringPage.xaml.cs create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind create mode 100644 Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Assets/Strings/en-US/Resources.resw b/Microsoft.Toolkit.Uwp.SampleApp/Assets/Strings/en-US/Resources.resw new file mode 100644 index 00000000000..7c909c61815 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/Assets/Strings/en-US/Resources.resw @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hello! + + + Resource String Markup Extension + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Assets/Strings/es-ES/Resources.resw b/Microsoft.Toolkit.Uwp.SampleApp/Assets/Strings/es-ES/Resources.resw new file mode 100644 index 00000000000..531bd774c7e --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/Assets/Strings/es-ES/Resources.resw @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hola! + + + Resource String Markup Extension + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index 0a9bf08f523..bab9877f54b 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -276,6 +276,7 @@ + @@ -389,6 +390,8 @@ PreserveNewest + + @@ -512,6 +515,9 @@ MetadataControlPage.xaml + + ResourceStringPage.xaml + AttachedDropShadowPage.xaml @@ -644,6 +650,7 @@ + @@ -999,6 +1006,10 @@ Designer + + MSBuild:Compile + Designer + MSBuild:Compile Designer diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceString.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceString.png new file mode 100644 index 0000000000000000000000000000000000000000..ceb19f779807a013a9b5a82a34e4644d3cfb6444 GIT binary patch literal 6035 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 QptNR=AB0@3|F0ka4{m_*t^fc4 literal 0 HcmV?d00001 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringPage.xaml new file mode 100644 index 00000000000..e4dd6f8eebd --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringPage.xaml @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringPage.xaml.cs new file mode 100644 index 00000000000..d31dc3b797c --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringPage.xaml.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages +{ + /// + /// A page that shows how to use the offset behavior. + /// + public sealed partial class ResourceStringPage : IXamlRenderListener + { + /// + /// Initializes a new instance of the class. + /// + public ResourceStringPage() + { + InitializeComponent(); + } + + public void OnXamlRendered(FrameworkElement control) + { + } + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind new file mode 100644 index 00000000000..f5339bb643b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind @@ -0,0 +1,50 @@ + + + + + + + + + + + + + Get a greating from the English resource context: + + + + Or get a greeting from the Spanish resource context: + + + + + See our blog post on #ifdef Windows: + Use a Custom Resource Markup Extension to Succeed at UI String Globalization! + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml index a3a001645f7..78d31dc5f06 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml @@ -39,6 +39,8 @@ + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 8cdfcc3a619..ef72da0f55f 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -1266,11 +1266,20 @@ "Name": "OnDevice", "Type": "OnDevicePage", "About": "The OnDevice markup extension allows you to customize UI appearance on a per-DeviceFamily basis.", - "CodeUrl" : "https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/main/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/OnDeviceExtension.cs", + "CodeUrl": "https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/main/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/OnDeviceExtension.cs", "Icon": "/SamplePages/OnDevice/OnDevice.png", "XamlCodeFile": "OnDeviceXaml.bind", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/OnDeviceMarkup.md" }, + { + "Name": "ResourceString", + "Type": "ResourceStringPage", + "About": "The ResourceString markup extension allows you to easily access resource strings through bindings instead of Uid.", + "CodeUrl": "https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/main/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs", + "Icon": "/SamplePages/ResourceString/ResourceString.png", + "XamlCodeFile": "ResourceStringXaml.bind", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/ResourceStringMarkup.md" + }, { "Name": "IconExtensions", "Type": "IconExtensionsPage", @@ -1284,7 +1293,7 @@ "Name": "EnumValuesExtension", "Type": "EnumValuesExtensionPage", "About": "The EnumValuesExtension markup extension allows you to easily retrieve a collection of all values from an enum type.", - "CodeUrl" : "https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/main/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/EnumValuesExtension.cs", + "CodeUrl": "https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/main/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/EnumValuesExtension.cs", "Icon": "/Assets/Helpers.png", "XamlCodeFile": "EnumValuesExtensionXaml.bind", "CodeFile": "EnumValuesExtensionCode.bind", diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs new file mode 100644 index 00000000000..c2f2d91d598 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Windows.ApplicationModel.Resources; +using Windows.UI.Xaml.Markup; + +namespace Microsoft.Toolkit.Uwp.UI +{ + /// + /// Xaml extension to return a string value from resource file associated with a resource key + /// + [MarkupExtensionReturnType(ReturnType = typeof(string))] + public sealed class ResourceStringExtension : MarkupExtension + { + private static ResourceLoader resourceLoader = ResourceLoader.GetForCurrentView(); + + /// + /// Gets or sets associated ID from resource strings + /// + public string Name + { + get; set; + } + + /// + /// Gets or sets the associated language resource to use (ie: "es-ES") + /// default is the OS language of current view + /// + public string Language { get; set; } + + /// + protected override object ProvideValue() + { + if (string.IsNullOrEmpty(Language)) + { + return resourceLoader.GetString(this.Name); + } + else + { + // not using ResourceContext.GetForCurrentView + var resourceContext = new Windows.ApplicationModel.Resources.Core.ResourceContext + { + Languages = new string[] { Language } + }; + var resourceMap = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap.GetSubtree("Resources"); + return resourceMap.GetValue(this.Name, resourceContext).ValueAsString; + } + } + } +} diff --git a/Windows Community Toolkit.sln b/Windows Community Toolkit.sln index c09b6446a9a..21f6aa5ef03 100644 --- a/Windows Community Toolkit.sln +++ b/Windows Community Toolkit.sln @@ -205,6 +205,8 @@ Global EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {719C43C6-8753-4395-ADAA-2FCC70F76BF3}.Debug|Any CPU.ActiveCfg = Debug|x86 + {719C43C6-8753-4395-ADAA-2FCC70F76BF3}.Debug|Any CPU.Build.0 = Debug|x86 + {719C43C6-8753-4395-ADAA-2FCC70F76BF3}.Debug|Any CPU.Deploy.0 = Debug|x86 {719C43C6-8753-4395-ADAA-2FCC70F76BF3}.Debug|ARM.ActiveCfg = Debug|ARM {719C43C6-8753-4395-ADAA-2FCC70F76BF3}.Debug|ARM.Build.0 = Debug|ARM {719C43C6-8753-4395-ADAA-2FCC70F76BF3}.Debug|ARM.Deploy.0 = Debug|ARM @@ -387,6 +389,7 @@ Global {BAB1CAF4-C400-4A7F-A987-C576DE63CFFD}.Release|x86.Build.0 = Release|x86 {BAB1CAF4-C400-4A7F-A987-C576DE63CFFD}.Release|x86.Deploy.0 = Release|x86 {1AE2CB5C-58A0-4F12-8E6F-2CD4AAADB34C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1AE2CB5C-58A0-4F12-8E6F-2CD4AAADB34C}.Debug|Any CPU.Build.0 = Debug|Any CPU {1AE2CB5C-58A0-4F12-8E6F-2CD4AAADB34C}.Debug|ARM.ActiveCfg = Debug|ARM {1AE2CB5C-58A0-4F12-8E6F-2CD4AAADB34C}.Debug|ARM.Build.0 = Debug|ARM {1AE2CB5C-58A0-4F12-8E6F-2CD4AAADB34C}.Debug|ARM64.ActiveCfg = Debug|ARM64 From 7e8414d6e3352e473b5af96a5a5de59ff5b44300 Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Thu, 14 Oct 2021 13:20:24 -0700 Subject: [PATCH 02/12] Update to independant view and a compiled bind option --- .../Markup/ResourceStringExtension.cs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index c2f2d91d598..23e43260ed4 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI [MarkupExtensionReturnType(ReturnType = typeof(string))] public sealed class ResourceStringExtension : MarkupExtension { - private static ResourceLoader resourceLoader = ResourceLoader.GetForCurrentView(); + private static ResourceLoader resourceLoader = ResourceLoader.GetForViewIndependentUse(); /// /// Gets or sets associated ID from resource strings @@ -32,19 +32,31 @@ public string Name /// protected override object ProvideValue() { - if (string.IsNullOrEmpty(Language)) + return GetValue(this.Name, this.Language); + } + + /// + /// Gets a string value from resource file associated with a resource key + /// + /// Resource key name + /// optional language of the associated resource to use (ie: "es-ES") + /// default is the OS language of current view + /// a string value from resource file associated with a resource key + public static string GetValue(string name, string language = "") + { + if (string.IsNullOrEmpty(language)) { - return resourceLoader.GetString(this.Name); + return resourceLoader.GetString(name); } else { // not using ResourceContext.GetForCurrentView var resourceContext = new Windows.ApplicationModel.Resources.Core.ResourceContext { - Languages = new string[] { Language } + Languages = new string[] { language } }; var resourceMap = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap.GetSubtree("Resources"); - return resourceMap.GetValue(this.Name, resourceContext).ValueAsString; + return resourceMap.GetValue(name, resourceContext).ValueAsString; } } } From ef2ca9e022ce0d6e93d16c92efa19cddf4794ea3 Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Thu, 14 Oct 2021 13:41:57 -0700 Subject: [PATCH 03/12] Update ResourceString Sample to show x:Bind option --- .../ResourceString/ResourceStringXaml.bind | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind index f5339bb643b..6c45c093103 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind @@ -39,6 +39,18 @@ + + You can alternatively get a greeting using x:Bind for optimized compiled bind: + + + {x:Bind ui:ResourceStringExtension.GetValue('HelloText', 'es-ES')} + + + From 2371ccb42b2f5f163d7d6fa6c2fd2396deafbb51 Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Fri, 15 Oct 2021 11:24:55 -0700 Subject: [PATCH 04/12] Update Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs Co-authored-by: Sergio Pedri --- .../Extensions/Markup/ResourceStringExtension.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index 23e43260ed4..448f9bb8def 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -18,10 +18,7 @@ public sealed class ResourceStringExtension : MarkupExtension /// /// Gets or sets associated ID from resource strings /// - public string Name - { - get; set; - } + public string Name { get; set; } /// /// Gets or sets the associated language resource to use (ie: "es-ES") From 6eccb91cffa37b702560f3899a85d6c3a04d2b2b Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Fri, 15 Oct 2021 11:25:04 -0700 Subject: [PATCH 05/12] Update Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs Co-authored-by: Sergio Pedri --- .../Extensions/Markup/ResourceStringExtension.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index 448f9bb8def..c1935ce60cb 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -48,10 +48,7 @@ public static string GetValue(string name, string language = "") else { // not using ResourceContext.GetForCurrentView - var resourceContext = new Windows.ApplicationModel.Resources.Core.ResourceContext - { - Languages = new string[] { language } - }; + ResourceContext resourceContext = new() { Languages = new[] { language } }; var resourceMap = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap.GetSubtree("Resources"); return resourceMap.GetValue(name, resourceContext).ValueAsString; } From ac18713e01f6d5e529c41716f7ece99cd6e6731f Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Fri, 15 Oct 2021 11:25:22 -0700 Subject: [PATCH 06/12] Update Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs Co-authored-by: Sergio Pedri --- .../Extensions/Markup/ResourceStringExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index c1935ce60cb..ca346d19bf6 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -47,7 +47,7 @@ public static string GetValue(string name, string language = "") } else { - // not using ResourceContext.GetForCurrentView + // Not using ResourceContext.GetForCurrentView ResourceContext resourceContext = new() { Languages = new[] { language } }; var resourceMap = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap.GetSubtree("Resources"); return resourceMap.GetValue(name, resourceContext).ValueAsString; From 152106be4698088b3886465e8b725b80c981da4f Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Fri, 15 Oct 2021 11:25:33 -0700 Subject: [PATCH 07/12] Update Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs Co-authored-by: Sergio Pedri --- .../Extensions/Markup/ResourceStringExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index ca346d19bf6..e6a768c93e8 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -8,7 +8,7 @@ namespace Microsoft.Toolkit.Uwp.UI { /// - /// Xaml extension to return a string value from resource file associated with a resource key + /// Xaml extension to return a value from resource file associated with a resource key /// [MarkupExtensionReturnType(ReturnType = typeof(string))] public sealed class ResourceStringExtension : MarkupExtension From 5bb070ded35f77e7913b31de56102c01411edb41 Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Fri, 15 Oct 2021 11:26:16 -0700 Subject: [PATCH 08/12] Update Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs Co-authored-by: Sergio Pedri --- .../Extensions/Markup/ResourceStringExtension.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index e6a768c93e8..05b60387da5 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -50,6 +50,7 @@ public static string GetValue(string name, string language = "") // Not using ResourceContext.GetForCurrentView ResourceContext resourceContext = new() { Languages = new[] { language } }; var resourceMap = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap.GetSubtree("Resources"); + return resourceMap.GetValue(name, resourceContext).ValueAsString; } } From 3c2123ae23de670bc0907f64924a6d36cd2cb584 Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Fri, 15 Oct 2021 13:29:06 -0700 Subject: [PATCH 09/12] Updating Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs Per comments in PR --- .../ResourceString/ResourceStringXaml.bind | 2 +- .../Markup/ResourceStringExtension.cs | 29 +++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind index 6c45c093103..1866543024d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind @@ -52,7 +52,7 @@ See our blog post on #ifdef Windows: Use a Custom Resource Markup Extension to Succeed at UI String Globalization! diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index 05b60387da5..161707340ee 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using Windows.ApplicationModel.Resources; +using Windows.ApplicationModel.Resources.Core; using Windows.UI.Xaml.Markup; namespace Microsoft.Toolkit.Uwp.UI @@ -16,13 +17,13 @@ public sealed class ResourceStringExtension : MarkupExtension private static ResourceLoader resourceLoader = ResourceLoader.GetForViewIndependentUse(); /// - /// Gets or sets associated ID from resource strings + /// Gets or sets associated ID from resource strings. /// public string Name { get; set; } /// - /// Gets or sets the associated language resource to use (ie: "es-ES") - /// default is the OS language of current view + /// Gets or sets the associated language resource to use (ie: "es-ES"). + /// Defaults to the OS language of current view. /// public string Language { get; set; } @@ -33,26 +34,24 @@ protected override object ProvideValue() } /// - /// Gets a string value from resource file associated with a resource key + /// Gets a string value from resource file associated with a resource key. /// - /// Resource key name - /// optional language of the associated resource to use (ie: "es-ES") - /// default is the OS language of current view - /// a string value from resource file associated with a resource key + /// Resource key name. + /// optional language of the associated resource to use (ie: "es-ES"). + /// default is the OS language of current view. + /// a string value from resource file associated with a resource key. public static string GetValue(string name, string language = "") { if (string.IsNullOrEmpty(language)) { return resourceLoader.GetString(name); } - else - { - // Not using ResourceContext.GetForCurrentView - ResourceContext resourceContext = new() { Languages = new[] { language } }; - var resourceMap = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap.GetSubtree("Resources"); - return resourceMap.GetValue(name, resourceContext).ValueAsString; - } + // Not using ResourceContext.GetForCurrentView nor GetForViewIndependentUse + ResourceContext resourceContext = new() { Languages = new[] { language } }; + var resourceMap = ResourceManager.Current.MainResourceMap.GetSubtree("Resources"); + + return resourceMap.GetValue(name, resourceContext).ValueAsString; } } } From 79a38c2ac863e7f2d9d1f413ee6efe2255e68074 Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Tue, 2 Nov 2021 12:45:39 -0700 Subject: [PATCH 10/12] ResourceStringExtension: adding additional function to accomodate optional value in x:Bind compiled function --- .../Extensions/Markup/ResourceStringExtension.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index 161707340ee..b8eb7851bd3 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -33,6 +33,18 @@ protected override object ProvideValue() return GetValue(this.Name, this.Language); } + /// + /// Gets a string value from resource file associated with a resource key. + /// + /// Resource key name. + /// a string value from resource file associated with a resource key. + public static string GetValue(string name) + { + // This function is needed to accomodate compiled function usage without second paramater, + // which doesn't work with optional values. + return resourceLoader.GetString(name); + } + /// /// Gets a string value from resource file associated with a resource key. /// @@ -44,7 +56,7 @@ public static string GetValue(string name, string language = "") { if (string.IsNullOrEmpty(language)) { - return resourceLoader.GetString(name); + return GetValue(name); } // Not using ResourceContext.GetForCurrentView nor GetForViewIndependentUse @@ -53,5 +65,6 @@ public static string GetValue(string name, string language = "") return resourceMap.GetValue(name, resourceContext).ValueAsString; } + } } From d22658b3dbe7e67f01b8965834af3ab4a51aa31e Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Tue, 2 Nov 2021 12:56:23 -0700 Subject: [PATCH 11/12] ResourceStringExtension Sample: adding additional function notation that accomodates no optional value in x:Bind compiled function --- .../SamplePages/ResourceString/ResourceStringXaml.bind | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind index 1866543024d..95d0caeff69 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind @@ -44,6 +44,11 @@ Style="{StaticResource BodyTextBlockStyle}"> You can alternatively get a greeting using x:Bind for optimized compiled bind: + + {x:Bind ui:ResourceStringExtension.GetValue('HelloText')} + From f7f68fad42821fe6bd9679eb3364c9bb1d949852 Mon Sep 17 00:00:00 2001 From: Herrick Spencer Date: Sat, 12 Feb 2022 20:11:03 -0800 Subject: [PATCH 12/12] Comments from PR --- .../ResourceString/ResourceStringXaml.bind | 46 +++++++++---------- .../Markup/ResourceStringExtension.cs | 8 ++-- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind index 95d0caeff69..100516a97fa 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ResourceString/ResourceStringXaml.bind @@ -7,58 +7,58 @@ xmlns:core="using:Microsoft.Xaml.Interactions.Core" xmlns:ui="using:Microsoft.Toolkit.Uwp.UI" mc:Ignorable="d"> - - - - + FontSize="30" + TextWrapping="Wrap"/> + FontSize="20" + Margin="10,20,0,0" + TextWrapping="Wrap"/> + FontSize="20" + Margin="10,20,0,0" + TextWrapping="Wrap"> Get a greating from the English resource context: + FontSize="20" + Margin="10,20,0,0" + TextWrapping="Wrap"> Or get a greeting from the Spanish resource context: + FontSize="20" + Margin="10,20,0,0" + TextWrapping="Wrap"> You can alternatively get a greeting using x:Bind for optimized compiled bind: + FontSize="18" + Margin="20,0,0,0" + TextWrapping="Wrap"> {x:Bind ui:ResourceStringExtension.GetValue('HelloText')} + FontSize="18" + Margin="20,0,0,0" + TextWrapping="Wrap"> {x:Bind ui:ResourceStringExtension.GetValue('HelloText', 'es-ES')} + FontSize="16" + Margin="10,20,0,0" + TextWrapping="Wrap"> See our blog post on #ifdef Windows: Use a Custom Resource Markup Extension to Succeed at UI String Globalization! diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs index b8eb7851bd3..be877b32952 100644 --- a/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs +++ b/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/ResourceStringExtension.cs @@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Uwp.UI [MarkupExtensionReturnType(ReturnType = typeof(string))] public sealed class ResourceStringExtension : MarkupExtension { - private static ResourceLoader resourceLoader = ResourceLoader.GetForViewIndependentUse(); + private static readonly ResourceLoader resourceLoader = ResourceLoader.GetForViewIndependentUse(); /// /// Gets or sets associated ID from resource strings. @@ -37,7 +37,7 @@ protected override object ProvideValue() /// Gets a string value from resource file associated with a resource key. /// /// Resource key name. - /// a string value from resource file associated with a resource key. + /// A string value from resource file associated with a resource key. public static string GetValue(string name) { // This function is needed to accomodate compiled function usage without second paramater, @@ -49,9 +49,9 @@ public static string GetValue(string name) /// Gets a string value from resource file associated with a resource key. /// /// Resource key name. - /// optional language of the associated resource to use (ie: "es-ES"). + /// Optional language of the associated resource to use (ie: "es-ES"). /// default is the OS language of current view. - /// a string value from resource file associated with a resource key. + /// A string value from resource file associated with a resource key. public static string GetValue(string name, string language = "") { if (string.IsNullOrEmpty(language))