Reputation: 198
The WinUI for Desktop Template Studio template contains a file Resources.resw file in the project folder Strings/en-us. The ShellPage has XAML Uid properties which map to keys in this file for navigation page titles. I am trying to store other localized strings in this file and access them in code.
I am using the following code to extract the string when a particular page is loaded:
public sealed partial class TransactionDetailPage : Page
{
public TransactionDetailPage()
{
this.InitializeComponent();
Loaded += (s, e) =>
{
var rl = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
App.CurrentPageTitle = rl.GetString("TransactionDetailPage.Title");
};
}
}
However, I am getting the following runtime error and despite much googling have been unable to find a solution.
System.Runtime.InteropServices.COMException:
Resource Contexts may not be created on threads that do not have a CoreWindow. (0x80073B27)
I would appreciate any help solving this problem.
Upvotes: 2
Views: 931
Reputation: 139
A slight adjustment to the answer by @Andrew KeepCoding to allow for shorter keys when looking for localized resources defined in the calling assembly:
I use the ResourceManager
instead of ResourceLoader
so that I can access the main resource map as well as any other sub-map within the application.
using Microsoft.Windows.ApplicationModel.Resources;
public static class ResourceExtensions
{
private static readonly ResourceMap Strings = new ResourceManager().MainResourceMap;
public static string? GetLocalized(this string? value)
{
if (value == null)
{
return value;
}
var localized = Strings.TryGetValue(value);
return localized != null ? localized.ValueAsString : value;
}
public static string? GetLocalizedMine(this string? value)
{
if (value == null)
{
return value;
}
var assemblyName = Assembly.GetCallingAssembly().GetName().Name;
var subMap = Strings.GetSubtree($"{Assembly.GetCallingAssembly().GetName().Name}/Strings");
if (subMap == null)
{
Debug.WriteLine($"Resource map for assembly `{assemblyName}` does not exist.");
return value;
}
var localized = subMap.TryGetValue(value);
return localized != null ? localized.ValueAsString : value;
}
}
Upvotes: 0
Reputation: 13666
The Template Studio should create this class:
ResourceExtensions.cs
using Microsoft.Windows.ApplicationModel.Resources;
namespace TemplateStudioWinUI3LocalizerSampleApp.Helpers;
public static class ResourceExtensions
{
private static readonly ResourceLoader _resourceLoader = new();
public static string GetLocalized(this string resourceKey) => _resourceLoader.GetString(resourceKey);
}
so you should be able to:
Loaded += (s, e) =>
{
App.CurrentPageTitle = "TransactionDetailPage.Title".GetLocalized();
}
Upvotes: 2