• wpf z


    Finding an ancestor of a WPF dependency object

    This is a simple snippet which helps you to find a specified parent of a given WPF dependency object somewhere in its visual tree:

    (Snippet updated 2009.09.14)

    /// <summary>
    /// Finds a parent of a given item on the visual tree.
    /// </summary>
    /// <typeparam name="T">The type of the queried item.</typeparam>
    /// <param name="child">A direct or indirect child of the
    /// queried item.</param>
    /// <returns>The first parent item that matches the submitted
    /// type parameter. If not matching item can be found, a null
    /// reference is being returned.</returns>
    public static T TryFindParent<T>(this DependencyObject child)
        where T : DependencyObject
    {
      //get parent item
      DependencyObject parentObject = GetParentObject(child);
    
      //we've reached the end of the tree
      if (parentObject == null) return null;
    
      //check if the parent matches the type we're looking for
      T parent = parentObject as T;
      if (parent != null)
      {
        return parent;
      }
      else
      {
        //use recursion to proceed with next level
        return TryFindParent<T>(parentObject);
      }
    }
    
    /// <summary>
    /// This method is an alternative to WPF's
    /// <see cref="VisualTreeHelper.GetParent"/> method, which also
    /// supports content elements. Keep in mind that for content element,
    /// this method falls back to the logical tree of the element!
    /// </summary>
    /// <param name="child">The item to be processed.</param>
    /// <returns>The submitted item's parent, if available. Otherwise
    /// null.</returns>
    public static DependencyObject GetParentObject(this DependencyObject child)
    {
      if (child == null) return null;
      
      //handle content elements separately
      ContentElement contentElement = child as ContentElement;
      if (contentElement != null)
      {
        DependencyObject parent = ContentOperations.GetParent(contentElement);
        if (parent != null) return parent;
    
        FrameworkContentElement fce = contentElement as FrameworkContentElement;
        return fce != null ? fce.Parent : null;
      }
    
      //also try searching for parent in framework elements (such as DockPanel, etc)
      FrameworkElement frameworkElement = child as FrameworkElement;
      if (frameworkElement != null)
      {
        DependencyObject parent = frameworkElement.Parent;
        if (parent != null) return parent;
      }
    
      //if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
      return VisualTreeHelper.GetParent(child);
    }

    This snippet works with arbitrary dependency objects that are of Type Visual or Visual3D. So let’s say you need a reference to the Window that hosts a given Button control somewhere, all you need is this:

    Button myButton = ...
    Window parentWindow = UIHelper.TryFindParent<Window>(myButton);

    The above TryFindParent method also makes it easy to get an item at a given position. The method below performs a hit test based on a given position. If hit testing does not return the requested item (e.g. a clicked CheckBox on a tree, while you are keen on the TreeViewItem that hosts the CheckBox), the procedure delegates the lookup to TryFindParent.

    This comes in very handy for mouse-related events if you just need to now what’s under your mouse pointer:

    /// <summary>
    /// Tries to locate a given item within the visual tree,
    /// starting with the dependency object at a given position. 
    /// </summary>
    /// <typeparam name="T">The type of the element to be found
    /// on the visual tree of the element at the given location.</typeparam>
    /// <param name="reference">The main element which is used to perform
    /// hit testing.</param>
    /// <param name="point">The position to be evaluated on the origin.</param>
    public static T TryFindFromPoint<T>(UIElement reference, Point point)
      where T:DependencyObject
    {
      DependencyObject element = reference.InputHitTest(point)
                                   as DependencyObject;
      if (element == null) return null;
      else if (element is T) return (T)element;
      else return TryFindParent<T>(element);
    }
  • 相关阅读:
    JavaScript学习笔记(六)——Map、Set与iterable
    JavaScript学习笔记(五)——条件判断与循环
    JavaScript学习笔记(四)——对象
    JavaScript学习笔记(三)——数组
    抽象代数 第三章 群
    进栈序列为(1,2,3..,n)有多少种出栈顺序
    Win10 快捷键
    主项定理Master Method
    算法导论笔记 第三十章 多项式与快速傅里叶变化
    算法导论笔记 第二十九章 线性规划
  • 原文地址:https://www.cnblogs.com/zeroone/p/6719499.html
Copyright © 2020-2023  润新知