VisualTreeHelper类的使用

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">
            <Grid Name="container" HorizontalAlignment="Left" VerticalAlignment="Top" Tapped="container_Tapped_1">
                <Rectangle Name="rectangle" Width="300" Height="200" Fill="Red" />
                <Border Name="border" Width="200" Height="120" Background="Green" />
                <ScrollViewer Name="scrollViewer" Width="150" Height="150" Background="Blue" />
            </Grid>
            <TextBlock Name="lblMsg" FontSize="14.667" Margin="0 10 0 0" />
        </StackPanel>
    </Grid>
/*
 * 演示 VisualTreeHelper 的应用
 * 
 * VisualTreeHelper - 访问可视树的帮助类
 *     GetChildrenCount(DependencyObject reference) - 获取指定的元素内的子元素的数量
 *     DependencyObject GetChild(DependencyObject reference, int childIndex) - 获取指定的元素内的,指定索引位置的子元素
 *     GetParent(DependencyObject reference) - 获取指定的元素的父元素
 *     FindElementsInHostCoordinates(Point intersectingPoint, UIElement subtree, bool includeAllElements) - 查找某一点内的全部元素(包括控件模板内的元素)
 *         intersectingPoint - 指定的点的坐标
 *         subtree - 在此元素内进行查找,包括此元素
 *         includeAllElements
 *             true - 查找全部元素,包括 IsHitTestVisible 为 true 的和 IsHitTestVisible 为 false 的
 *             false - 仅查找 IsHitTestVisible 为 true 的元素
 *     FindElementsInHostCoordinates(Rect intersectingRect, UIElement subtree, bool includeAllElements) - 查找某一矩形区域内的全部元素(包括控件模板内的元素)
 *         intersectingRect - 指定的矩形区域
 *         subtree - 在此元素内进行查找,包括此元素
 *         includeAllElements
 *             true - 查找全部元素,包括 IsHitTestVisible 为 true 的和 IsHitTestVisible 为 false 的
 *             false - 仅查找 IsHitTestVisible 为 true 的元素
 */
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            this.Loaded += VisualTree_Loaded;
        }

        void VisualTree_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            // 获取 container 中包含的元素
            lblMsg.Text = "container 中包含的元素有:";
            int numVisuals = VisualTreeHelper.GetChildrenCount(container);
            for (int i = 0; i < numVisuals; i++)
            {
                DependencyObject element = VisualTreeHelper.GetChild(container, i);
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += element.GetType().ToString();
            }


            lblMsg.Text += Environment.NewLine;
            lblMsg.Text += Environment.NewLine;


            // 在 scrollViewer 控件自身的模板中查找类型为 ScrollBar 的名为 VerticalScrollBar 的控件
            lblMsg.Text += "查找 scrollViewer 中的名为“VerticalScrollBar”的 ScrollBar 控件:";
            lblMsg.Text += Environment.NewLine;
            ScrollBar scrollBar = GetVisualChild<ScrollBar>(scrollViewer, "VerticalScrollBar");
            if (scrollBar != null)
                lblMsg.Text += "找到了";
            else
                lblMsg.Text += "未找到";
        }

        private void container_Tapped_1(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
        {
            // 获取鼠标单击的位置,container 范围内所包含的全部元素(包括控件模板内的元素)
            lblMsg.Text = "鼠标单击的位置,container 内,包含的元素有:";
            IEnumerable<UIElement> elementsPoint = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), container, true);
            var elementsPointEnumerator = elementsPoint.GetEnumerator();
            while (elementsPointEnumerator.MoveNext())
            {
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += elementsPointEnumerator.Current.GetType().ToString();
            }


            lblMsg.Text += Environment.NewLine;
            lblMsg.Text += Environment.NewLine;


            // 获取以鼠标单击的位置为顶点,100*100 大小的矩形内,container 范围内所包含的全部元素(包括控件模板内的元素)
            lblMsg.Text += "以鼠标单击的位置为顶点,100*100 大小的矩形范围内,container 内,包含的元素有:";
            IEnumerable<UIElement> elementsRect = VisualTreeHelper.FindElementsInHostCoordinates(new Rect(e.GetPosition(null), new Size(100, 100)), container, true);
            var elementsRectEnumerator = elementsRect.GetEnumerator();
            while (elementsRectEnumerator.MoveNext())
            {
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += elementsRectEnumerator.Current.GetType().ToString();
            }
        }

        /// <summary>
        /// 获取指定元素内部的指定名称的 FrameworkElement
        /// </summary>
        private T GetVisualChild<T>(DependencyObject parent, string name) where T : FrameworkElement
        {
            // T 是引用类型则为 null,T 是值类型则为 0
            T child = default(T);

            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                DependencyObject obj = VisualTreeHelper.GetChild(parent, i);
                child = obj as T;

                if (child == null || child.Name != name)
                    child = GetVisualChild<T>(obj, name);
                if (child != null)
                    break;
            }
            return child;
        }

    }

 

posted on 2013-03-28 13:09  JackSlaterYu  阅读(703)  评论(0编辑  收藏  举报