using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Windows; namespace CMM.Language { public class CulturesHelper { private bool _isFoundInstalledCultures = false; const string LanguageFolder = "/Language;component"; const string ResourceLocalPath = "pack://application:,," + LanguageFolder; const string LanguageFileName = "StringResources"; public List SupportedCultures { get; private set; } = new List(); public CulturesHelper() => Init(); private void Init() { if (!_isFoundInstalledCultures) { var cultureInfo = new CultureInfo(""); var Languages = GetAllLanguageResource(); GetAllLanguageResource().ForEach(file => { try { string cultureName = file.Substring(file.IndexOf(".") + 1).Replace(".xaml", ""); cultureInfo = CultureInfo.GetCultureInfo(cultureName); if (cultureInfo != null) { SupportedCultures.Add(cultureInfo); } } catch (ArgumentException) { } }); _isFoundInstalledCultures = true; } } /// /// 增加Language的XMAL檔 /// private static List GetAllLanguageResource() { var Languages = new List(); string uriPath = ResourceLocalPath + "/" + LanguageFileName; Languages.Add(uriPath + ".en.xaml"); Languages.Add(uriPath + ".es.xaml"); Languages.Add(uriPath + ".fr.xaml"); Languages.Add(uriPath + ".de.xaml"); Languages.Add(uriPath + ".zh.xaml"); Languages.Add(uriPath + ".ja.xaml"); Languages.Add(uriPath + ".pt.xaml"); Languages.Add(uriPath + ".it.xaml"); Languages.Add(uriPath + ".hi.xaml"); return Languages; } /// /// Auto-detect and apply system language /// public void ApplySystemLanguage() { var systemCulture = CultureInfo.CurrentUICulture; var matchedCulture = FindBestMatchingCulture(systemCulture); ChangeCulture(matchedCulture); } /// /// Find the best matching supported culture for the given culture /// private CultureInfo FindBestMatchingCulture(CultureInfo culture) { // Try exact match first var exactMatch = SupportedCultures.FirstOrDefault(c => c.Name.Equals(culture.Name, StringComparison.OrdinalIgnoreCase)); if (exactMatch != null) return exactMatch; // Try matching by two-letter ISO language name var languageMatch = SupportedCultures.FirstOrDefault(c => c.TwoLetterISOLanguageName.Equals(culture.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase)); if (languageMatch != null) return languageMatch; // Default to English return SupportedCultures.FirstOrDefault(c => c.Name == "en") ?? SupportedCultures.First(); } public void ChangeCulture(string cultureName) { var cultureInfo = CultureInfo.GetCultureInfo(cultureName); if (cultureInfo != null) { ChangeCulture(cultureInfo); } } /// /// 切換語系 /// public void ChangeCulture(CultureInfo culture) { if (SupportedCultures.Contains(culture)) { var existsRD = Application.Current.Resources.MergedDictionaries .Where(x => x.Source.OriginalString.StartsWith(ResourceLocalPath, StringComparison.CurrentCultureIgnoreCase) || x.Source.OriginalString.StartsWith(LanguageFolder, StringComparison.CurrentCultureIgnoreCase)) .FirstOrDefault(); if (existsRD == null) return; var resourceFile = $"{ResourceLocalPath}/{LanguageFileName}.{culture.Name}.xaml"; var res = new ResourceDictionary() { Source = new Uri(resourceFile, UriKind.Absolute) }; Application.Current.Resources.MergedDictionaries.Remove(existsRD); Application.Current.Resources.MergedDictionaries.Add(res); } } } public static class Lang { public static string Find(string key) { if (Application.Current == null) return null; try { return (string)Application.Current.FindResource(key); } catch { return string.Empty; } } } }