A playground for demonstrating how to use resx & resw in dotnet 7, WinUI, .Net Standard 2.0 and UWP.
Copy the resw xml text as resx file
Use System.Resources.ResourceManager
to GetString
Original Resw Created by Visual Studio
Build Action: PRIResource
Original Resx Created by Visual Studio
Build Action: Embedded resource
Custom Tool: ResXFileCodeGenerator
<EmbeddedResource Update="Strings\Resource1.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resource1.Designer.cs</LastGenOutput>
</EmbeddedResource>
Create a String Resource Class
TestStringResource/SR.cs
private readonly ResourceManager _rm = new(BaseName, Assembly.GetExecutingAssembly());
var res = loader._rm.GetString(name, culture);
Project Structure
TestStringResource
├── Strings
│ ├── Resource.en-US.resx
│ └── Resource.fr-FR.resx
├── SR.cs
└── TestClass.cs
TestStringResourceApp
└── Program.cs
TestStringResourceWinUI
├── Extensions
│ └── ResourceExtensions.cs
├── Services
│ └── LocalizationService.cs
└── Strings
├── en-US
│ ├── Resources.resw
└── fr-FR
└── Resources.resw
TestStringResourceWinUIApp
├── Assets
│ └── ...
├── Strings
│ ├── en-US
│ │ ├── Resources.resw
│ └── fr-FR
│ └── Resources.resw
├── App.xaml
│ └── App.xaml.cs
├── MainPage.xaml
│ └── MainPage.xaml.cs
├── MainViewModel.cs
└── Package.appxmanifest
Project Structure
TestStringResourceStandard
├── Strings
│ ├── Resource.en-US.resx
│ └── Resource.fr-FR.resx
├── SR.cs
└── TestClass.cs
TestStringResourceStandardApp
└── Program.cs
TestStringResourceUWPApp
├── Assets
│ └── ...
├── App.xaml
│ └── App.xaml.cs
├── MainPage.xaml
│ └── MainPage.xaml.cs
├── MainViewModel.cs
└── Package.appxmanifest
How to create user-defined exceptions with localized exception messages
- ResourceManager
- Localization
- resx
- Exception
var resourceManager = new ResourceManager("FULLY_QUALIFIED_NAME_OF_RESOURCE_FILE", Assembly.GetExecutingAssembly());
throw new StudentNotFoundException(resourceManager.GetString("StudentNotFound"), "John");
- dotnet 7
- Localization
- txt, restext, resw
ResourceManager rm = new ResourceManager("Strings", typeof(Example).Assembly);
string timeString = rm.GetString("TimeHeader");
CultureInfo newCulture = new CultureInfo(cultures[cultureNdx]);
Thread.CurrentThread.CurrentCulture = newCulture;
Thread.CurrentThread.CurrentUICulture = newCulture;
string greeting = String.Format("The current culture is {0}.\n{1}",
Thread.CurrentThread.CurrentUICulture.Name,
rm.GetString("HelloString"));
microsoft/referencesource/System.Workflow.Activities/SR.cs
- ResourceManager
- String Resource
public SRDescriptionAttribute(string description, string resourceSet)
{
ResourceManager rm = new ResourceManager(resourceSet, Assembly.GetExecutingAssembly());
DescriptionValue = rm.GetString(description);
System.Diagnostics.Debug.Assert(DescriptionValue != null, string.Format(CultureInfo.CurrentCulture, "String resource {0} not found.", description));
}
...
internal sealed class SR
{
static SR loader = null;
ResourceManager resources;
internal SR()
{
resources = new System.Resources.ResourceManager("System.Workflow.Activities.StringResources", Assembly.GetExecutingAssembly());
}
private static SR GetLoader()
{
if (loader == null)
loader = new SR();
return loader;
}
...
internal static string GetString(CultureInfo culture, string name, params object[] args)
{
SR sys = GetLoader();
if (sys == null)
return null;
string res = sys.resources.GetString(name, culture);
System.Diagnostics.Debug.Assert(res != null, string.Format(CultureInfo.CurrentCulture, "String resource {0} not found.", name));
if (args != null && args.Length > 0)
{
return String.Format(CultureInfo.CurrentCulture, res, args);
}
else
{
return res;
}
}
internal const string Activity = "Activity";
...
private const string Error_InvalidStateActivityParent = "Error_InvalidStateActivityParent";
internal static string GetError_InvalidStateActivityParent()
{
return GetString(Error_InvalidStateActivityParent,
typeof(StateActivity).Name);
}
microsoft/referencesource/Microsoft.Activities.Build/SR.resx
<data name="InspectingClass" xml:space="preserve">
<value>XAML build extension '{0}' is inspecting class '{1}'.</value>
</data>
Include a localized string message in every exception
FileReaderException NewFileIOException()
{
string description = "My NewFileIOException Description";
return new FileReaderException(description);
}
...
throw NewFileIOException();
microsoft/WindowsAppSDK-Samples/Samples/ResourceManagement/cs-winui/ClassLibrary/Class.cs
- WinUI
using Microsoft.Windows.ApplicationModel.Resources;
...
public string GetClassLibrarySampleString()
{
var resourceManager = new ResourceManager();
return resourceManager.MainResourceMap.GetValue("ClassLibrary/ClassLibraryResources/ClassLibrarySampleString").ValueAsString;
}
- A ResourceLoader object encapsulates a particular ResourceMap and a ResourceContext, combined in a simple API.
var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
var text = resourceLoader.GetString("Farewell");
Application resources and localization sample Windows-universal-samples/Samples/ApplicationResources/cs/scenario10.xaml.cs
var context = ResourceContext.GetForCurrentView().Clone();
var dimensionMap = ResourceManager.Current.MainResourceMap.GetSubtree("dimensions");
void Scenario10_ShowCandidates(string resourceId, IReadOnlyList<ResourceCandidate> resourceCandidates) {
foreach (var candidate in resourceCandidates)
{
var value = candidate.ValueAsString;
foreach (var qualifier in candidate.Qualifiers)
{
var qualifierName = qualifier.QualifierName;
var qualifierValue = qualifier.QualifierValue;