123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- using System;
- using System.Windows;
- using System.Windows.Data;
- using System.Windows.Markup;
- using HandyControl.Properties.Langs;
- namespace HandyControl.Tools.Extension;
- public class LangExtension : MarkupExtension
- {
- private readonly DependencyObject _proxy;
- public LangExtension()
- {
- _proxy = new DependencyObject();
- Source = LangProvider.Instance;
- }
- public LangExtension(string key) : this()
- {
- Key = key;
- }
- public static readonly DependencyProperty KeyProperty = DependencyProperty.RegisterAttached(
- "Key", typeof(object), typeof(LangExtension), new PropertyMetadata(default));
- public object Key
- {
- get => _proxy.GetValue(KeyProperty);
- set => _proxy.SetValue(KeyProperty, value);
- }
- private static readonly DependencyProperty TargetPropertyProperty = DependencyProperty.RegisterAttached(
- "TargetProperty", typeof(DependencyProperty), typeof(LangExtension), new PropertyMetadata(default(DependencyProperty)));
- private static void SetTargetProperty(DependencyObject element, DependencyProperty value)
- => element.SetValue(TargetPropertyProperty, value);
- private static DependencyProperty GetTargetProperty(DependencyObject element)
- => (DependencyProperty) element.GetValue(TargetPropertyProperty);
- public BindingMode Mode { get; set; }
- public IValueConverter Converter { get; set; }
- public object ConverterParameter { get; set; }
- public object Source { get; set; }
- public override object ProvideValue(IServiceProvider serviceProvider)
- {
- if (!(serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget provideValueTarget)) return this;
- if (provideValueTarget.TargetObject.GetType().FullName == "System.Windows.SharedDp") return this;
- if (!(provideValueTarget.TargetObject is DependencyObject targetObject)) return this;
- if (!(provideValueTarget.TargetProperty is DependencyProperty targetProperty)) return this;
- switch (Key)
- {
- case string key:
- {
- var binding = CreateLangBinding(key);
- BindingOperations.SetBinding(targetObject, targetProperty, binding);
- return binding.ProvideValue(serviceProvider);
- }
- case Binding keyBinding when targetObject is FrameworkElement element:
- {
- if (element.DataContext != null)
- {
- var binding = SetLangBinding(element, targetProperty, keyBinding.Path, element.DataContext);
- return binding.ProvideValue(serviceProvider);
- }
- SetTargetProperty(element, targetProperty);
- element.DataContextChanged += LangExtension_DataContextChanged;
- break;
- }
- case Binding keyBinding when targetObject is FrameworkContentElement element:
- {
- if (element.DataContext != null)
- {
- var binding = SetLangBinding(element, targetProperty, keyBinding.Path, element.DataContext);
- return binding.ProvideValue(serviceProvider);
- }
- SetTargetProperty(element, targetProperty);
- element.DataContextChanged += LangExtension_DataContextChanged;
- break;
- }
- }
- return string.Empty;
- }
- private void LangExtension_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
- {
- switch (sender)
- {
- case FrameworkElement element:
- {
- element.DataContextChanged -= LangExtension_DataContextChanged;
- if (!(Key is Binding keyBinding)) return;
- var targetProperty = GetTargetProperty(element);
- SetTargetProperty(element, null);
- SetLangBinding(element, targetProperty, keyBinding.Path, element.DataContext);
- break;
- }
- case FrameworkContentElement element:
- {
- element.DataContextChanged -= LangExtension_DataContextChanged;
- if (!(Key is Binding keyBinding)) return;
- var targetProperty = GetTargetProperty(element);
- SetTargetProperty(element, null);
- SetLangBinding(element, targetProperty, keyBinding.Path, element.DataContext);
- break;
- }
- }
- }
- private BindingBase SetLangBinding(DependencyObject targetObject, DependencyProperty targetProperty, PropertyPath path, object dataContext)
- {
- if (targetProperty == null) return null;
- BindingOperations.SetBinding(targetObject, targetProperty, new Binding
- {
- Path = path,
- Source = dataContext,
- Mode = BindingMode.OneWay
- });
- var key = targetObject.GetValue(targetProperty) as string;
- if (string.IsNullOrEmpty(key)) return null;
- var binding = CreateLangBinding(key);
- BindingOperations.SetBinding(targetObject, targetProperty, binding);
- return binding;
- }
- private BindingBase CreateLangBinding(string key) => new Binding(key)
- {
- Converter = Converter,
- ConverterParameter = ConverterParameter,
- UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
- Source = Source,
- Mode = BindingMode.OneWay
- };
- }
|