Esempio n. 1
0
        private void RegisterParentNotifier()
        {
            parentChangedNotifier = new ParentChangedNotifier(this, () =>
            {
                parentChangedNotifier.Dispose();
                parentChangedNotifier = null;
                var targetObject      = this.Parent;
                if (targetObject != null)
                {
                    var properties = GetDependencyProperties(targetObject);
                    foreach (var p in properties)
                    {
                        if (targetObject.GetValue(p) == this)
                        {
                            targetInfo = new TargetInfo(targetObject, p, p.PropertyType, -1);

                            Binding binding            = new Binding("Content");
                            binding.Source             = this;
                            binding.Converter          = this.Converter;
                            binding.ConverterParameter = this.ConverterParameter;
                            binding.Mode = BindingMode.OneWay;
                            BindingOperations.SetBinding(targetObject, p, binding);
                            UpdateNewValue();
                        }
                    }
                }
            });
        }
Esempio n. 2
0
        /// <summary>
        /// Tries to get a value that is stored somewhere in the visual tree above this <see cref="DependencyObject"/>.
        /// <para>If this is not available, it will register a <see cref="ParentChangedNotifier"/> on the last element.</para>
        /// </summary>
        /// <typeparam name="T">The return type.</typeparam>
        /// <param name="target">The <see cref="DependencyObject"/>.</param>
        /// <param name="GetFunction">The function that gets the value from a <see cref="DependencyObject"/>.</param>
        /// <param name="ParentChangedAction">The notification action on the change event of the Parent property.</param>
        /// <param name="parentNotifiers">A dictionary of already registered notifiers.</param>
        /// <returns>The value, if possible.</returns>
        public static T GetValueOrRegisterParentNotifier <T>(
            this DependencyObject target,
            Func <DependencyObject, T> GetFunction,
            Action <DependencyObject> ParentChangedAction,
            ParentNotifiers parentNotifiers)
        {
            var ret = default(T);

            if (target == null)
            {
                return(ret);
            }

            var depObj     = target;
            var weakTarget = new WeakReference(target);

            while (ret == null)
            {
                // Try to get the value using the provided GetFunction.
                ret = GetFunction(depObj);

                if (ret != null && parentNotifiers.ContainsKey(target))
                {
                    parentNotifiers.Remove(target);
                }

                // Try to get the parent using the visual tree helper. This may fail on some occations.
#if !SILVERLIGHT
                if (!(depObj is Visual) && !(depObj is Visual3D) && !(depObj is FrameworkContentElement))
                {
                    break;
                }

                if (depObj is Window)
                {
                    break;
                }
#endif
                DependencyObject depObjParent = null;

#if !SILVERLIGHT
                if (depObj is FrameworkContentElement)
                {
                    depObjParent = ((FrameworkContentElement)depObj).Parent;
                }
                else
                {
                    try { depObjParent = depObj.GetParent(false); }
                    catch { depObjParent = null; }
                }
#endif

                if (depObjParent == null)
                {
                    try { depObjParent = depObj.GetParent(true); }
                    catch { break; }
                }

                // If this failed, try again using the Parent property (sometimes this is not covered by the VisualTreeHelper class :-P.
                if (depObjParent == null && depObj is FrameworkElement)
                {
                    depObjParent = ((FrameworkElement)depObj).Parent;
                }

                if (ret == null && depObjParent == null)
                {
                    // Try to establish a notification on changes of the Parent property of dp.
                    if (depObj is FrameworkElement && !parentNotifiers.ContainsKey(target))
                    {
                        var pcn = new ParentChangedNotifier((FrameworkElement)depObj, () =>
                        {
                            var localTarget = (DependencyObject)weakTarget.Target;
                            if (!weakTarget.IsAlive)
                            {
                                return;
                            }

                            // Call the action...
                            ParentChangedAction(localTarget);
                            // ...and remove the notifier - it will probably not be used again.
                            if (parentNotifiers.ContainsKey(localTarget))
                            {
                                parentNotifiers.Remove(localTarget);
                            }
                        });

                        parentNotifiers.Add(target, pcn);
                    }
                    break;
                }

                // Assign the parent to the current DependencyObject and start the next iteration.
                depObj = depObjParent;
            }

            return(ret);
        }
 /// <summary>
 /// Adds the key-value-pair.
 /// </summary>
 /// <param name="target">The target key object.</param>
 /// <param name="parentChangedNotifier">The notifier.</param>
 public void Add(DependencyObject target, ParentChangedNotifier parentChangedNotifier)
 {
     _inner.Add(new WeakReference <DependencyObject>(target), new WeakReference <ParentChangedNotifier>(parentChangedNotifier));
 }