using System; using System.ComponentModel; using System.Windows; using System.Windows.Data; using System.Windows.Markup; using TeamAAS.Localization; namespace TeamAAS.Localization { /// /// XAML 标记扩展:支持动态翻译,语言切换时自动刷新 /// 用法:Content="{loc:Translate '保存配置'}" /// [MarkupExtensionReturnType(typeof(BindingExpression))] public class TranslateExtension : MarkupExtension { /// /// 要翻译的原文(中文) /// [ConstructorArgument("key")] public string Key { get; set; } /// /// 可选的上下文(用于消歧义) /// public string Context { get; set; } /// /// 无参构造函数 /// public TranslateExtension() { } /// /// 单参数构造函数:支持 {loc:Translate '保存配置'} 语法 /// public TranslateExtension(string key) { Key = key; } public override object ProvideValue(IServiceProvider serviceProvider) { if (string.IsNullOrWhiteSpace(Key)) return "[未设置翻译Key]"; // 在设计时返回原文(避免设计器报错) if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) return Key; // 创建绑定:绑定到 TranslationProxy 的 Value 属性 // TranslationProxy 监听语言切换事件,自动更新翻译 var proxy = new TranslationProxy(Key, Context); var binding = new Binding("Value") { Source = proxy, Mode = BindingMode.OneWay }; // 如果能获取目标对象,返回绑定表达式;否则返回当前翻译 if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target) { if (target.TargetObject is DependencyObject && target.TargetProperty is DependencyProperty) { return binding.ProvideValue(serviceProvider); } } // fallback:直接返回翻译结果 return proxy.Value; } } /// /// 翻译代理:监听语言切换事件,自动更新翻译 /// internal class TranslationProxy : INotifyPropertyChanged { private readonly string _key; private readonly string _context; public TranslationProxy(string key, string context = null) { _key = key; _context = context; // 监听语言切换事件 GlobalLocalizationManager.Instance.LanguageChanged += OnLanguageChanged; } /// /// 当前翻译结果 /// public string Value => GlobalLocalizationManager.Instance.Translate(_key, _context); private void OnLanguageChanged(object sender, EventArgs e) { // 语言切换时通知绑定刷新 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value))); } public event PropertyChangedEventHandler PropertyChanged; } }