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);
    }
  • 相关阅读:
    Python xrange与range的区别返回的结果不一样
    matlab画立方体
    python查询数据类型
    Ubuntu下安装微信(electronic-wechat)
    python判断数组中是否有重复元素
    python构建数组
    Numpy中np.max(即np.amax)的用法
    你不知道C#只带有 get 访问器的属性是只读属性?
    Windows 平台安装配置 MongoDB
    一日一技:Ocelot网关使用IdentityServer4认证
  • 原文地址:https://www.cnblogs.com/zeroone/p/6719499.html
Copyright © 2011-2022 走看看