TranslateExtension.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System;
  2. using System.ComponentModel;
  3. using System.Windows;
  4. using System.Windows.Data;
  5. using System.Windows.Markup;
  6. using TeamAAS.Localization;
  7. namespace TeamAAS.Localization
  8. {
  9. /// <summary>
  10. /// XAML 标记扩展:支持动态翻译,语言切换时自动刷新
  11. /// 用法:Content="{loc:Translate '保存配置'}"
  12. /// </summary>
  13. [MarkupExtensionReturnType(typeof(BindingExpression))]
  14. public class TranslateExtension : MarkupExtension
  15. {
  16. /// <summary>
  17. /// 要翻译的原文(中文)
  18. /// </summary>
  19. [ConstructorArgument("key")]
  20. public string Key { get; set; }
  21. /// <summary>
  22. /// 可选的上下文(用于消歧义)
  23. /// </summary>
  24. public string Context { get; set; }
  25. /// <summary>
  26. /// 无参构造函数
  27. /// </summary>
  28. public TranslateExtension()
  29. {
  30. }
  31. /// <summary>
  32. /// 单参数构造函数:支持 {loc:Translate '保存配置'} 语法
  33. /// </summary>
  34. public TranslateExtension(string key)
  35. {
  36. Key = key;
  37. }
  38. public override object ProvideValue(IServiceProvider serviceProvider)
  39. {
  40. if (string.IsNullOrWhiteSpace(Key))
  41. return "[未设置翻译Key]";
  42. // 在设计时返回原文(避免设计器报错)
  43. if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
  44. return Key;
  45. // 创建绑定:绑定到 TranslationProxy 的 Value 属性
  46. // TranslationProxy 监听语言切换事件,自动更新翻译
  47. var proxy = new TranslationProxy(Key, Context);
  48. var binding = new Binding("Value")
  49. {
  50. Source = proxy,
  51. Mode = BindingMode.OneWay
  52. };
  53. // 如果能获取目标对象,返回绑定表达式;否则返回当前翻译
  54. if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target)
  55. {
  56. if (target.TargetObject is DependencyObject && target.TargetProperty is DependencyProperty)
  57. {
  58. return binding.ProvideValue(serviceProvider);
  59. }
  60. }
  61. // fallback:直接返回翻译结果
  62. return proxy.Value;
  63. }
  64. }
  65. /// <summary>
  66. /// 翻译代理:监听语言切换事件,自动更新翻译
  67. /// </summary>
  68. internal class TranslationProxy : INotifyPropertyChanged
  69. {
  70. private readonly string _key;
  71. private readonly string _context;
  72. public TranslationProxy(string key, string context = null)
  73. {
  74. _key = key;
  75. _context = context;
  76. // 监听语言切换事件
  77. GlobalLocalizationManager.Instance.LanguageChanged += OnLanguageChanged;
  78. }
  79. /// <summary>
  80. /// 当前翻译结果
  81. /// </summary>
  82. public string Value => GlobalLocalizationManager.Instance.Translate(_key, _context);
  83. private void OnLanguageChanged(object sender, EventArgs e)
  84. {
  85. // 语言切换时通知绑定刷新
  86. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
  87. }
  88. public event PropertyChangedEventHandler PropertyChanged;
  89. }
  90. }