I was talking to a fellow dev about why the Resource Manager cannot support languages that the phone platform itself does not support. However, I thought that there probably would be a workaround…and here it is.
Step 1 – Create your basic project
Create phone project, by default this will create;
Resources\AppResources.resx
Step 2 – Add a test resource
Open the AppResources and add a new string called ‘ColourLabel’. I’m making the horrible assumption that you have defaulted to en-US so please enter the value of ‘Color’.
Step 3 – Add a new resource culture
Project->Add->Resource, e.g. AppResources.en-GB.resx
This should have copied our resource string from the master resource, so please change ‘ColourLabel’ to the correct spelling of ‘Colour’
Step 4 – Add a new unknown resource culture
Copy AppResource.en-GB.resx over to AppResources.en-XX.resx
Change ‘ColourLabel’ value from ‘Colour’ to our alien value of ‘ColourXX’
Step 5 – Change Build Action
If you try to use the ResourceManager to access en-XX it will fail because the culture is alien to the platform. So starts the workaround, change the BuildAction of en-XX to ‘Content’
Step 6 – Execute the resource manager
Running the following code…
AlienResourceManager britishResourceManager = new AlienResourceManager("en-GB");
System.Diagnostics.Debug.WriteLine("en-GB: " + britishResourceManager.GetString("ColourLabel"));
AlienResourceManager alienResourceManager = new AlienResourceManager("en-XX");
System.Diagnostics.Debug.WriteLine("en-XX: " + alienResourceManager.GetString("ColourLabel"));
results in the following output;
en-GB: Colour
en-XX: ColourXX
all done?
It’s fairly obvious that isn’t standard code, but it’s actually just a little over-riding of the standard ResourceManager. Here is my quick version, hope you find it useful.
public class AlienResourceManager : ResourceManager
{
private string alienCultureName;
private Dictionary alienStrings = null;
private CultureInfo currentCulture;
public AlienResourceManager(string alienCultureName) : base("MyPhoneApp.Resources.AppResources", typeof(AppResources).Assembly)
{
this.alienCultureName = alienCultureName;
try
{
CultureInfo ci = new CultureInfo(alienCultureName);
this.currentCulture = ci;
}
catch (Exception)
{
LoadAlienStrings(alienCultureName);
this.IsAlienCulture = true;
}
}
private void LoadAlienStrings(string alienCultureName)
{
var localisation = Application.GetResourceStream(new Uri("Resources/AppResources." + alienCultureName + ".resx", UriKind.Relative));
StreamReader resx = new StreamReader(localisation.Stream);
string resXml = resx.ReadToEnd();
XElement resourceFile = XElement.Parse(resXml);
this.alienStrings = new Dictionary();
var resourceStrings =
(from r in resourceFile.Descendants("data")
select new { Name= r.Attribute("name").Value, Value = r.Element("value").Value}).ToList();
resourceStrings.ForEach(r => this.alienStrings.Add(r.Name, r.Value));
}
public bool IsAlienCulture { get; set; }
public override string GetString(string name)
{
if (this.IsAlienCulture)
{
return this.alienStrings[name];
}
else
{
return base.GetString(name, currentCulture);
}
}
}