zoukankan      html  css  js  c++  java
  • 正确理解WPF中的TemplatedParent (转贴)

    http://blog.csdn.net/idebian/article/details/8761388

    (注:Logical Tree中文称为逻辑树,Visual Tree中文称为可视化树或者视觉树,由于名称不是很统一,文中统一用英文名称代表两个概念,况且VisualTreeHelper和LogicalTreeHelper也是WPF中提供的类名称)

    众所周知WPF中的Logical Tree是逻辑上定义的元素层次树,而实际上显示在屏幕上的元素层次树是Visual Tree,Visual Tree是Logical Tree节点扩充后的的产物。因此从Visual Tree的角度上看(Visual Tree当然是完整的一个),Logical Tree被分割成一段一段的,而这些段与段的连接点,就是和TemplatedParent有关。

    这个概念在WPF类模型中是FrameworkElement.TemplatedParent属性。WPF中的模板(数据模板和控件模板)都可以扩展Logical Tree,那么模板所修饰的对象就是模板中元素的TemplatedParent,此时模板元素和修饰对象都会出现在Visual Tree中,但模板元素肯定不属于被修饰元素的Logical Tree,但是模板有自己的Logical Tree,两个Logical Tree是分开的,但是通过TemplatedParent,两者之间又有联系。

    说再多不如实例形象,来看下面示例代码:

    这是一个简单的ContentControl,它的Content是一个按钮,然后定义了控件模板和数据模板,代码中一些关键元素有Name属性,我们在后续讨论就以Name属性的值来引用这些元素

    <ContentControl Name="contentControl">  
      
                  
      
        <!-- 控件模板 -->  
      
        <ContentControl.Template>  
      
            <ControlTemplate TargetType="ContentControl">  
      
                <Border Name="bd1">  
      
                    <ContentPresenter Name="cp1" ContentSource="Content"/>  
      
                </Border>  
      
             </ControlTemplate>  
      
         </ContentControl.Template>  
      
                  
      
         <!-- 数据模板 -->  
      
         <ContentControl.ContentTemplate>  
      
             <DataTemplate>  
      
                 <Border Name="bd2">  
      
                     <ContentPresenter Name="cp2" Content="{Binding}" />  
      
                 </Border>  
      
              </DataTemplate>  
      
          </ContentControl.ContentTemplate>  
      
                  
      
          <!-- 逻辑孩子 -->  
      
          <Button Name="btn">按钮</Button>  
      
    </ContentControl> 
    

      这个ContentControl的Visual Tree如下图:

    图中相同颜色的节点代表它们属于同一个Logical Tree,可以看出来,整个Visual Tree分成多个Logical Tree,而这些Logical Tree是分开的,比如上面代码中的两个Border(名称是bd1和bd2),它们的Parent属性的值都是null,即没有逻辑父节点。但是这些逻辑树通过TemplatedParent是互相有联系的。比如控件模板中的元素的TemplatedParent指代最上方的ContentControl,而数据模板元素的TemplatedParent则是控件模板内的ContentPresenter元素。

    通过代码也可以验证这些:(bd1, bd2, cp1, cp2分别代表控件模板和数据模板中的Border和ContentPresenter)

        private void Button_Click(object sender, RoutedEventArgs e)  
          
        {  
          
            var bd1 = (Border)contentControl.Template.FindName("bd1", contentControl);  
          
            var cp1 = (ContentPresenter)contentControl.Template.FindName("cp1", contentControl);  
          
            var bd2 = (Border)contentControl.ContentTemplate.FindName("bd2", cp1);  
          
            var cp2 = (ContentPresenter)contentControl.ContentTemplate.FindName("cp2", cp1);  
          
           
          
            PrintInfo(bd1, cp1, bd2, cp2, btn);  
          
        }  
          
           
          
        void PrintInfo(params FrameworkElement[] eles)  
          
        {  
          
            string s = "";  
          
            foreach (var ele in eles)  
          
                s += String.Format("{2}
    Parent: {0}
    TemplatedParent: {1}
    
    ", ele.Parent, ele.TemplatedParent, ele.Name);  
          
            MessageBox.Show(s);  
          
        }  
  • 相关阅读:
    凤凰传奇
    信息孤岛
    别了,中珠
    吃苦要趁早
    触动——beyond歌词
    走出舒适区,迎接挑战
    创新永存
    信息时代
    变色龙时代——创新
    Java基本的数据类型
  • 原文地址:https://www.cnblogs.com/macleo/p/7429108.html
Copyright © 2011-2022 走看看