using System; using System.Collections.Generic; using System.Linq; using System.Xml; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace Billing.Languages { internal class Resource { public static string TitleDateFormat => Text(nameof(TitleDateFormat)); public static string Cash => Text(nameof(Cash)); public static string CreditCard => Text(nameof(CreditCard)); public static string DebitCard => Text(nameof(DebitCard)); public static string ElecAccount => Text(nameof(ElecAccount)); static readonly Dictionary dict = new(); public static string Text(string name, params object[] args) { string current = App.CurrentCulture.PlatformString; if (!dict.TryGetValue(current, out LanguageResource lang)) { lang = new LanguageResource(App.CurrentCulture); dict.Add(current, 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 { var ns = lang.GetNamespace(); var langId = $"{ns}.Languages.{lang.Language}.xml"; var langCodeId = $"{ns}.Languages.{lang.LanguageCode}.xml"; var assembly = typeof(LanguageResource).Assembly; var name = assembly.GetManifestResourceNames().FirstOrDefault(n => string.Equals(n, langId, StringComparison.OrdinalIgnoreCase) || string.Equals(n, langCodeId, StringComparison.OrdinalIgnoreCase)); if (name == null) { name = $"{ns}.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) { Helper.Error("language.ctor", $"failed to load json resource: {lang}, {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 Resource.Text(Text); } } }