zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    lua时间戳和日期转换及踩坑【转】
    Js正则表达式验证输入是否有特殊字符【转】
    PHP数据类型转换【转】
    JavaScript indexOf() 方法
    CSS文本下划线 删除线 上划线【转】
    PHP中把stdClass Object转array的几个方法【转】
    2020软件工程作业02
    2020软件工程作业01
    2020 CCPC Wannafly Winter Camp Day1-F-乘法
    牛客-装货物
  • 原文地址:https://www.cnblogs.com/zeroone/p/6719499.html
Copyright © 2011-2022 走看看