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;
}
}