TranslateExtension.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. using System;
  2. using System.ComponentModel;
  3. using System.Windows;
  4. using System.Windows.Data;
  5. using System.Windows.Markup;
  6. namespace TeamAAS.Localization
  7. {
  8. /// <summary>
  9. /// XAML 标记扩展(共享版,供 Core / FlowEngine / 插件等程序集使用):
  10. /// 支持 {loc:Translate '保存配置'},语言切换时自动刷新。
  11. /// 主程序 TeamAAS.exe 内的 TeamAAS.Localization.TranslateExtension 与本类等价,
  12. /// 两者查询同一个 GlobalLocalizationManager 单例。
  13. /// </summary>
  14. [MarkupExtensionReturnType(typeof(BindingExpression))]
  15. public class TranslateExtension : MarkupExtension
  16. {
  17. /// <summary>要翻译的原文(中文)</summary>
  18. [ConstructorArgument("key")]
  19. public string Key { get; set; }
  20. /// <summary>可选的上下文(用于消歧义)</summary>
  21. public string Context { get; set; }
  22. public TranslateExtension()
  23. {
  24. }
  25. public TranslateExtension(string key)
  26. {
  27. Key = key;
  28. }
  29. public override object ProvideValue(IServiceProvider serviceProvider)
  30. {
  31. if (string.IsNullOrWhiteSpace(Key))
  32. return "[未设置翻译Key]";
  33. if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
  34. return Key;
  35. var proxy = new SharedTranslationProxy(Key, Context);
  36. var binding = new Binding("Value")
  37. {
  38. Source = proxy,
  39. Mode = BindingMode.OneWay,
  40. };
  41. if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target
  42. && target.TargetObject is DependencyObject
  43. && target.TargetProperty is DependencyProperty)
  44. {
  45. return binding.ProvideValue(serviceProvider);
  46. }
  47. return proxy.Value;
  48. }
  49. }
  50. /// <summary>
  51. /// 翻译代理:监听语言切换事件,自动更新翻译
  52. /// </summary>
  53. internal class SharedTranslationProxy : INotifyPropertyChanged
  54. {
  55. private readonly string _key;
  56. private readonly string _context;
  57. public SharedTranslationProxy(string key, string context = null)
  58. {
  59. _key = key;
  60. _context = context;
  61. GlobalLocalizationManager.Instance.LanguageChanged += OnLanguageChanged;
  62. }
  63. public string Value => GlobalLocalizationManager.Instance.Translate(_key, _context);
  64. private void OnLanguageChanged(object sender, EventArgs e)
  65. {
  66. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
  67. }
  68. public event PropertyChangedEventHandler PropertyChanged;
  69. }
  70. }