using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Xml; using Gallery.Util; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace Gallery.Resources { public class Helper { private static readonly Dictionary dict = new(); public static string GetResource(string name, params object[] args) { if (!dict.TryGetValue(App.CurrentCulture.PlatformString, out LanguageResource lang)) { lang = new LanguageResource(App.CurrentCulture); dict.Add(App.CurrentCulture.PlatformString, lang); } if (args == null || args.Length == 0) { return lang[name]; } return string.Format(lang[name], args); } private class LanguageResource { private readonly Dictionary strings; public string this[string key] { get { if (strings != null && strings.TryGetValue(key, out string val)) { return val; } return key; } } public LanguageResource(PlatformCulture lang) { try { const string PROJECT = "Gallery"; const string PLATFORM = #if __IOS__ "iOS"; #elif __ANDROID__ "Droid"; #endif var langId = $"{PROJECT}.{PLATFORM}.Resources.Languages.{lang.Language}.xml"; var langCodeId = $"{PROJECT}.{PLATFORM}.Resources.Languages.{lang.LanguageCode}.xml"; var assembly = IntrospectionExtensions.GetTypeInfo(typeof(LanguageResource)).Assembly; var names = assembly.GetManifestResourceNames(); var name = names.FirstOrDefault(n => string.Equals(n, langId, StringComparison.OrdinalIgnoreCase) || string.Equals(n, langCodeId, StringComparison.OrdinalIgnoreCase)); if (name == null) { name = $"{PROJECT}.{PLATFORM}.Resources.Languages.zh-CN.xml"; } var xml = new XmlDocument(); using (var stream = assembly.GetManifestResourceStream(name)) { xml.Load(stream); } strings = new Dictionary(); foreach (XmlElement ele in xml.DocumentElement) { strings[ele.Name] = ele.InnerText; } } catch (Exception ex) { // load failed Log.Error("language.ctor", $"failed to load xml resource: {ex.Message}"); } } } } [ContentProperty(nameof(Text))] public class TextExtension : IMarkupExtension { public string Text { get; set; } public object ProvideValue(IServiceProvider serviceProvider) { if (Text == null) { return string.Empty; } return Helper.GetResource(Text); } } }