【msdn wpf forum翻译】TextBlock等类型的默认样式(implicit style)为何有时不起作用?

原文: 【msdn wpf forum翻译】TextBlock等类型的默认样式(implicit style)为何有时不起作用?

原文链接:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/148e95c6-6fb5-4399-8a56-41d0e0a72f1b


疑问:
以下代码定义了一个TextBlock的默认样式:
         < Style  TargetType =" {x:Type TextBlock} " >
            
< Style.Triggers >
                
< Trigger  Property ="Text"  Value ="" >
                    
< Setter  Property ="Visibility"  Value ="Collapsed" />
                
</ Trigger >
            
</ Style.Triggers >
        
</ Style >
以下是TreeView的一个 HierarchicalDataTemplate 的定义:
             < HierarchicalDataTemplate  DataType ="XYZ"  ItemsSource  =" {Binding} " >
                
< Grid  x:Uid ="Grid_7"  Width ="Auto"  Height ="Auto" >
                    
< Grid.ColumnDefinitions >
                        
< ColumnDefinition />
                        
< ColumnDefinition />
                        
< ColumnDefinition />
                        
< ColumnDefinition />
                    
</ Grid.ColumnDefinitions >
                    
< Grid.RowDefinitions >
                        
< RowDefinition />
                    
</ Grid.RowDefinitions >
                    
                    
< Image   Grid.Column ="0"  Grid.Row ="0"  Margin ="5,0,0,0" />
                    
< TextBlock   Grid.Column ="1"  Grid.Row ="0"  Padding ="5,0,0,0" />
                    
< TextBlock   Grid.Column ="2"  Grid.Row ="0"  Foreground ="Blue" Padding ="5,0,0,0" />
                    
< TextBlock   Grid.Column ="3"  Grid.Row ="0"  Foreground ="Red" Padding ="5,0,0,0" />                    
                
</ Grid >
            
</ HierarchicalDataTemplate >
之后,就算我们把 TextBlock的默认样式加到<TreeView.Resources> 之中,TextBlock也不会像预期的那样(预期:如果为空串时 Visibility == Collapsed)。
Johnny Q. 回答:
这个行为“by design”,简而言之,当一个直接继承自 FrameworkElement 的对象在一个 FrameworkTemplate 之中时,默认样式不起作用(当该样式定义在 FrameworkTemplate 之外的逻辑树的祖先节点时)。

This is by design, as far as I know (if it's good or bad, that can be debatable; maybe things will change in future releases). For short, default styles do not work with objects directly derived from FrameworkElement, when placed inside FrameworkTemplate. See also http://shevaspace.blogspot.com/2007/03/wtf-of-wpf-part-one-templating-styling.html


注:
http://shevaspace.blogspot.com/2007/03/wtf-of-wpf-part-one-templating-styling.html (需FQ)中更为详细的描述了这个问题,给出了一个可以在 xamlpad 中演示的例子,并指出了这个行为是在 FrameworkElement.FindImplicitStyleResource() 函数中进行限制的。 以下先给出链接中的例子:
Code


之后,我们打开 MS 发布的 wpf 的源代码(.net 3.0版)找到 FrameworkElement.FindImplicitStyleResource() 函数(注意参数重载,第一个参数为FrameworkElement的才是我们要找的):

Code


在这里我们只需要关注两个地方:
1. 第4、5行的注释。
2. 第18-24行的注释及代码。
可知,如果FrameworkElement的 非Control子类 的对象,其默认样式的搜索边界是其TemplateParent,而MS是出于性能优化的角度,进行这样的设计的。

为什么值得这样设计呢?以下是我的分析、推测:
我们知道,Control 类有 Template 属性,依照上面的结论, ControlTemplate 中 FrameworkElement 的非Control子类 的对象,其默认样式的搜索边界就是 其 TemplateParent,这样设计之后,搜索默认样式的速度就会被加快(可通过使用Reflector+Reflector's baml viewer add-in 查看 PresentationFramework.Aero.dll 中的 themes/aero.normalcolor.baml 来查看 Aero 主题的控件的默认Template)。

回到篇首提到的那个问题,我们可知,可通过在HierarchicalDataTemplate 的 Grid.Resource 中定义 TextBlock 的默认样式来实现提问者想要的功能。

猜你喜欢

转载自www.cnblogs.com/lonelyxmas/p/9292368.html