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); } } }