/// <summary>
        /// This method does the walk in the visual or logical tree, depending on the existance
        /// of the visual tree for the specified <paramref name="obj"/>.
        /// </summary>
        /// <remarks>
        /// The tree walk will use the visual tree if the specified <paramref name="obj"/>
        /// is a <see cref="Visual"/>, else it will use its logical tree.
        /// This method attaches change handlers to all relevant properties on the searched path.
        /// </remarks>
        /// <param name="obj">The object to get the parent of.</param>
        /// <param name="parent">The parent which was found navigating the visual or
        /// logical tree.</param>
        /// <param name="findParentMode">Specifies, which tree will be used to find the parent
        /// object.</param>
        /// <returns><c>true</c>, if a valid parent was found. In this case, the
        /// <paramref name="parent"/> parameter references a not-<c>null</c> parent.
        /// <c>false</c>, if no valid parent was found.</returns>
        protected bool FindParent(DependencyObject obj, out DependencyObject parent,
                                  FindParentMode findParentMode)
        {
            bool result;

            switch (findParentMode)
            {
            case FindParentMode.HybridPreferVisualTree:
                result = FindParent_VT(obj, out parent) || FindParent_LT(obj, out parent);
#if DEBUG_BINDINGS
                if (!result)
                {
                    DebugOutput("FindParent didn't find a parent in VT or LT for object '{0}'", obj);
                }
#endif
                return(result);

            case FindParentMode.HybridPreferLogicalTree:
                result = FindParent_LT(obj, out parent) || FindParent_VT(obj, out parent);
#if DEBUG_BINDINGS
                if (!result)
                {
                    DebugOutput("FindParent didn't find a parent in LT or VT for object '{0}'", obj);
                }
#endif
                return(result);

            case FindParentMode.LogicalTree:
                result = FindParent_LT(obj, out parent);
#if DEBUG_BINDINGS
                if (!result)
                {
                    DebugOutput("FindParent didn't find a parent in LT for object '{0}'", obj);
                }
#endif
                return(result);

            default:
                // Should never occur. If so, we have forgotten to handle a SourceType
                throw new NotImplementedException(
                          string.Format("FindParentMode '{0}' is not implemented", findParentMode));
            }
        }
    /// <summary>
    /// This method does the walk in the visual or logical tree, depending on the existance
    /// of the visual tree for the specified <paramref name="obj"/>.
    /// </summary>
    /// <remarks>
    /// The tree walk will use the visual tree if the specified <paramref name="obj"/>
    /// is a <see cref="Visual"/>, else it will use its logical tree.
    /// This method attaches change handlers to all relevant properties on the searched path.
    /// </remarks>
    /// <param name="obj">The object to get the parent of.</param>
    /// <param name="parent">The parent which was found navigating the visual or
    /// logical tree.</param>
    /// <param name="findParentMode">Specifies, which tree will be used to find the parent
    /// object.</param>
    /// <returns><c>true</c>, if a valid parent was found. In this case, the
    /// <paramref name="parent"/> parameter references a not-<c>null</c> parent.
    /// <c>false</c>, if no valid parent was found.</returns>
    protected bool FindParent(DependencyObject obj, out DependencyObject parent,
        FindParentMode findParentMode)
    {
      bool result;
      switch (findParentMode)
      {
        case FindParentMode.HybridPreferVisualTree:
          result = FindParent_VT(obj, out parent) || FindParent_LT(obj, out parent);
#if DEBUG_BINDINGS
          if (!result)
            DebugOutput("FindParent didn't find a parent in VT or LT for object '{0}'", obj);
#endif
          return result;
        case FindParentMode.HybridPreferLogicalTree:
          result = FindParent_LT(obj, out parent) || FindParent_VT(obj, out parent);
#if DEBUG_BINDINGS
          if (!result)
            DebugOutput("FindParent didn't find a parent in LT or VT for object '{0}'", obj);
#endif
          return result;
        case FindParentMode.LogicalTree:
          result = FindParent_LT(obj, out parent);
#if DEBUG_BINDINGS
          if (!result)
            DebugOutput("FindParent didn't find a parent in LT for object '{0}'", obj);
#endif
          return result;
        default:
          // Should never occur. If so, we have forgotten to handle a SourceType
          throw new NotImplementedException(
              string.Format("FindParentMode '{0}' is not implemented", findParentMode));
      }
    }
 protected bool FindAncestor(DependencyObject current, out DependencyObject ancestor, FindParentMode mode, int ancestorLevel, Type ancestorType)
 {
   ancestor = null;
   if (!FindParent(current, out current, mode)) // Start from the first ancestor
     return false;
   int ct = ancestorLevel;
   while (current != null)
   {
     if (ancestorType == null ||
         ancestorType.IsAssignableFrom(current.GetType()))
       ct -= 1;
     if (ct == 0)
     {
       ancestor = current;
       return true;
     }
     if (!FindParent(current, out current, mode))
       return false;
   }
   return false;
 }
        protected bool FindAncestor(DependencyObject current, out DependencyObject ancestor, FindParentMode mode, int ancestorLevel, Type ancestorType)
        {
            ancestor = null;
            if (!FindParent(current, out current, mode)) // Start from the first ancestor
            {
                return(false);
            }
            int ct = ancestorLevel;

            while (current != null)
            {
                if (ancestorType == null ||
                    ancestorType.IsAssignableFrom(current.GetType()))
                {
                    ct -= 1;
                }
                if (ct == 0)
                {
                    ancestor = current;
                    return(true);
                }
                if (!FindParent(current, out current, mode))
                {
                    return(false);
                }
            }
            return(false);
        }