`

WPF VisualTreeHelper and LogicalTreeHelper and various.

    博客分类:
  • WPF
wpf 
阅读更多

In this page: Understanding the Visual Tree and Logical Tree in WPF , the difference between the Visual Tree and Logical Tree is discussed.

 

Visual Tree and Logical Tree

 

In summary. 

 

Visual Tree

 

 

  • represents all of the elements in your UI which render to an output device (typically, the screen)
  • Used for rendering, event routing, and locating resource (if an element has no logical parent)

 

 

Logical Tree

 

  • Represents the essential structure of your UI. It closely matches the elemtns you declared in XAML, and excludes most visual elements create internally to help render the elements you declared.
  • WPF use logical tree to determine several things including dependency proeprty value inheritence, resource resolution and more.

 

 

How to walk down/up the VisualTree and the Logical Tree

 

with the Help of VisualTreeHelper, you can do 

 

 

  • VisualTreeHelper.GetParent(depObj)
  • VisualTreeHelper.GetChildren(depObj)

 

 

and with the help of LogicalTreeHelper, you can do 

 

 

  • LogicalTreeHelper.GetParent(depObj);
  • LogicalTreeHelper.GetChildren(depObj);

 

Below shows some helper function to help you find a parent of a specific type 

 

 

DependencyObject parent = ExVisualTreeHelper.FindVisualParent<UserControl>(this);

public static class ExVisualTreeHelper
{
    /// <summary>
    /// Finds the visual parent.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sender">The sender.</param>
    /// <returns></returns>
    public static T FindVisualParent<T>(DependencyObject sender) where T : DependencyObject
    {
        if (sender == null)
        {
            return (null);
        }
        else if (VisualTreeHelper.GetParent(sender) is T)
        {
            return (VisualTreeHelper.GetParent(sender) as T);
        }
        else
        {
            DependencyObject parent = VisualTreeHelper.GetParent(sender);
            return (FindVisualParent<T>(parent));
        }
    }
 

 

You can do the same for LogicalTree.

 

 

Remove Visual/Logical Child

You may sometimes require to remove a child from a visual tree or logical tree (actually still investigating when this is justified). 

 

There are two method for the class FrameworkElement.

 

FrameworkElement.RemoveLogicalChild 

FrameworkElement.RemoveVisualChild

 

But they are protected internal method. Generally there are two ways to get around this. 

 

 

  • inherit and override
  • reflection call. 

 

Below show the code to do the reflection call.

 

 

private System.Reflection.MethodInfo GetMethodInfo(string name)
        {
          if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");


          var windowType = typeof(FrameworkElement);
          var methodinfo = windowType.GetMethod(name, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod);

          if (methodinfo != null)
            return methodinfo;
          return null;
        }

        private void CallRemoveLogicalChild(FrameworkElement window, object child)
        {
          if (window == null) throw new ArgumentNullException("window");
          if (child == null) throw new ArgumentNullException("child");
          var method = GetMethodInfo("RemoveLogicalChild");
          if (method != null)
          {
            method.Invoke(window, new[] { child });
          }

        }

        private void CallRemoveVisualChild(FrameworkElement window, object child)
        {
          if (window == null) throw new ArgumentNullException("window");
          if (child == null) throw new ArgumentNullException("child");

          var method = GetMethodInfo("RemoveVisualChild");
          if (method != null)
          {
            method.Invoke(window, new[] { child });
          }
        }
 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics