using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Windows.Forms; namespace UAS_MES_NEW.PublicMethod { public class LanguageReload { private static readonly object _lock = new object(); private static JObject _root; private static string _loadedPath; private static string _defaultCulture = "en-US"; public static void Load(string filePath) { lock (_lock) { if (!File.Exists(filePath)) throw new FileNotFoundException("Language file not found", filePath); var text = File.ReadAllText(filePath, System.Text.Encoding.UTF8); _root = JObject.Parse(text); _loadedPath = filePath; // try to read a default culture from file if provided var metaDefault = _root["meta"]?["defaultCulture"]?.ToString(); if (!string.IsNullOrWhiteSpace(metaDefault)) _defaultCulture = metaDefault; } } public static string GetString(string key, string culture) { lock (_lock) { if (_root == null) return null; var node = _root["control"]?[key]; if (node == null) return null; var v = node[culture]?.ToString(); if (!string.IsNullOrEmpty(v)) return v; // fallback to default culture v = node[_defaultCulture]?.ToString(); if (!string.IsNullOrEmpty(v)) return v; // fallback to any available value var first = node.Children().FirstOrDefault()?.Value?.ToString(); return first; } } public static void ApplyToControl(Control ctrl, string culture) { if (ctrl == null) return; // For controls that expose Text property var value = GetString(ctrl.Name, culture); if (!string.IsNullOrEmpty(value)) { ctrl.Text = value; } // Special handling for ToolStrip / MenuStrip items if (ctrl is ToolStrip ts) { foreach (ToolStripItem item in ts.Items) { var v = GetString(item.Name, culture); if (!string.IsNullOrEmpty(v)) item.Text = v; } } // recursively apply to child controls foreach (Control child in ctrl.Controls) { ApplyToControl(child, culture); } } public static void ApplyToForm(Form form, string culture) { if (form == null) return; // 必须在 InitializeComponent() 之后调用 ApplyToControl(form, culture); } public static bool IsLoaded => _root != null; public static string LoadedPath => _loadedPath; public static string GetMessage(string key) { try { var ltObj = BaseUtil.GetCacheData("LanguageType"); var lt = ltObj == null ? "0" : ltObj.ToString(); var culture = lt == "1" ? "en-US" : lt == "2" ? "vi-VN" : "zh-CN"; var s = GetString(key, culture); if (!string.IsNullOrEmpty(s)) return s; // 回退到默认文化由 LocalizationProvider 处理,仍未找到则返回 key return key; } catch { return key; } } public static string Format(string key, params object[] args) { var format = GetMessage(key); try { return string.Format(format, args); } catch { return format; } } public static void ApplyLocalization(Form form, string culture, string langFilePath = null) { if (form == null) return; try { if (!IsLoaded) { if (string.IsNullOrEmpty(langFilePath)) throw new InvalidOperationException("语言文件未加载,请传入 langFilePath 或先调用 LocalizationProvider.Load"); Load(langFilePath); } // 1. 基本 Text / ToolStrip 项目处理(递归) ApplyToForm(form, culture); // 2. 处理 Designer 中声明为字段的 ColumnHeader:按字段名(如 columnHeader1)查找并设置 Text var formType = form.GetType(); var headerFields = formType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) .Where(f => f.FieldType == typeof(ColumnHeader)); foreach (var f in headerFields) { try { var header = f.GetValue(form) as ColumnHeader; if (header == null) continue; var key = f.Name; // e.g. "columnHeader1" var txt = GetString(key, culture); if (!string.IsNullOrEmpty(txt)) { header.Text = txt; } } catch { // 忽略单个列头设置错误 } } // 3. 处理控件上的 PlaceHolder / Placeholder 属性(自定义控件) ApplyPlaceholdersRecursive(form, culture); // 4. 如果需要,可在此加入对其它特殊控件/属性的处理 } catch (Exception ex) { // 仅做调试输出,生产环境可记录日志 System.Diagnostics.Debug.WriteLine("ApplyLocalization 错误: " + ex.Message); } } private static void ApplyPlaceholdersRecursive(Control parent, string culture) { foreach (Control ctrl in parent.Controls) { try { // 查找 PlaceHolder / Placeholder 属性(大小写兼容) var prop = ctrl.GetType().GetProperty("PlaceHolder", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? ctrl.GetType().GetProperty("Placeholder", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (prop != null && prop.CanWrite) { // 先尝试按 "控件名.PlaceHolder" 查找占位符翻译 var keyWithProp = $"{ctrl.Name}.PlaceHolder"; var val = GetString(keyWithProp, culture); if (string.IsNullOrEmpty(val)) { // 回退到按控件名直接查找 val = GetString(ctrl.Name, culture); } if (!string.IsNullOrEmpty(val)) { prop.SetValue(ctrl, val, null); } } } catch { // 忽略单控件占位符设置错误 } // 递归子控件 if (ctrl.HasChildren) { ApplyPlaceholdersRecursive(ctrl, culture); } } } } }