/// <summary> /// Sets a binding between a <see cref="DependencyObject"/> with its <see cref="DependencyProperty"/> /// or <see cref="PropertyInfo"/> and the LocalizeExtension<> /// </summary> /// <param name="targetObject">The target dependency object</param> /// <param name="targetProperty">The target dependency property</param> /// <returns>TRUE if the binding was setup successfully, otherwise FALSE (Binding already exists).</returns> /// <exception cref="ArgumentException">If the <paramref name="targetProperty"/> is /// not a <see cref="DependencyProperty"/> or <see cref="PropertyInfo"/>.</exception> public bool SetBinding(DependencyObject targetObject, object targetProperty) { if (!(targetProperty is DependencyProperty || targetProperty is PropertyInfo)) { throw new ArgumentException("The targetProperty should be a DependencyProperty or PropertyInfo!", "targetProperty"); } // indicates, if the target object was found bool foundInWeakReferences = false; // search for the target in the target object list foreach (KeyValuePair <WeakReference, object> wr in m_TargetObjects) { // if the target is the target of the weakreference if (wr.Key.Target == targetObject && wr.Value == targetProperty) { // set the flag to true and stop searching foundInWeakReferences = true; break; } } // if the target it's not collected already, collect it if (!foundInWeakReferences) { // if it's the first object, add an event handler too if (m_TargetObjects.Count == 0) { // add this localize extension to the WeakEventManager on LocalizeDictionary LocalizeDictionary.Instance.AddEventListener(this); } // add the target as an dependency object as weakreference to the dependency object list m_TargetObjects.Add(new WeakReference(targetObject), targetProperty); // adds this localize extension to the ObjectDependencyManager to ensure the lifetime along with the targetobject ObjectDependencyManager.AddObjectDependency(new WeakReference(targetObject), this); // set the initial value of the dependency property SetTargetValue(targetObject, targetProperty, FormatOutput(LocalizeDictionary.Instance.GetLocalizedObject <object>( Assembly, Dict, Key, GetForcedCultureOrDefault()))); // return true, the binding was successfully return(true); } // return false, the binding already exists return(false); }
/// <summary> /// Provides the Value for the first Binding /// </summary> /// <remarks> /// This method register the <see cref="EventHandler"/> <c>OnCultureChanged</c> on <c>LocalizeDictionary</c> /// to get an acknowledge of changing the culture, if the passed <see cref="TargetObjects"/> type of <see cref="DependencyObject"/>. /// /// !PROOF: On every single <see cref="UserControl"/>, Window, and Page, /// there is a new SparedDP reference, and so there is every time a new <c>LocalizeExtension</c>! /// Because of this, we don't need to notify every single DependencyObjects to update their value (for GC). /// </remarks> /// <param name="serviceProvider"> /// The <see cref="System.Windows.Markup.IProvideValueTarget"/> provided from the <see cref="MarkupExtension"/> /// </param> /// <returns>The founded item from the .resx directory or null if not founded</returns> /// <exception cref="System.InvalidOperationException"> /// thrown if <paramref name="serviceProvider"/> is not type of <see cref="System.Windows.Markup.IProvideValueTarget"/> /// </exception> public override object ProvideValue(IServiceProvider serviceProvider) { // try to cast the passed serviceProvider to a IProvideValueTarget IProvideValueTarget service = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; // if the cast fails, an exception will be thrown. (should never happen) if (service == null) { throw new InvalidOperationException("IProvideValueTarget service is unavailable"); } // if the service.TargetObject is a Binding, throw an exception if (service.TargetObject is System.Windows.Data.Binding) { throw new InvalidOperationException("Use as binding is not supported!"); } // declare a target property object targetProperty = null; // check if the service.TargetProperty is a DependencyProperty or a PropertyInfo if (service.TargetProperty is DependencyProperty || service.TargetProperty is PropertyInfo) { // set the target property to the service.TargetProperty targetProperty = service.TargetProperty; } // check if the target property is null if (targetProperty == null) { // return this. return(this); } // if the service.TargetObject is System.Windows.SharedDp (= not a DependencyObject), we return "this". // the SharedDp will call this instance later again. if (!(service.TargetObject is DependencyObject)) { // by returning "this", the provide value will be called later again. return(this); } // indicates, if the target object was found bool foundInWeakReferences = false; // search for the target in the target object list foreach (KeyValuePair <WeakReference, object> wr in m_TargetObjects) { // if the target is the target of the weakreference if (wr.Key.Target == service.TargetObject && wr.Value == service.TargetProperty) { // set the flag to true and stop searching foundInWeakReferences = true; break; } } // if the target is a dependency object and it's not collected already, collect it if (service.TargetObject is DependencyObject && !foundInWeakReferences) { // if it's the first object, add an event handler too if (m_TargetObjects.Count == 0) { // add this localize extension to the WeakEventManager on LocalizeDictionary LocalizeDictionary.Instance.AddEventListener(this); } // add the target as an dependency object as weakreference to the dependency object list m_TargetObjects.Add(new WeakReference(service.TargetObject), service.TargetProperty); // adds this localize extension to the ObjectDependencyManager to ensure the lifetime along with the targetobject ObjectDependencyManager.AddObjectDependency(new WeakReference(service.TargetObject), this); } // return the new value for the DependencyProperty return(LocalizeDictionary.Instance.GetLocalizedObject <object>(Assembly, Dict, Key, GetForcedCultureOrDefault())); }