我有点困惑,试图理解视觉树中的样式覆盖是如何工作的。
我有两个例子 - 第一个,定义DataGridCell
完美无缺,如图所示。
第二个,定义ToggleButton
,完全被忽略,但我很难找到第一个有效的原因,但第二个没有。任何人都可以提供任何见解吗?
DataGridCell
样式定义在DataGrid.Resources
:<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding hello}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridCell}"><!--DataGridCell is a child of DataGrid's Visual Tree -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Padding="10" Background="Red">
<ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
ToggleButton
Resources
中定义的样式将被忽略:<Expander>
<Expander.Resources>
<Style TargetType="{x:Type ToggleButton}"><!--ToggleButton is a child of Expander's Visual Tree-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock>Hello World!</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Expander.Resources>
<Expander.Header>Header</Expander.Header>
<Expander.Content>Body</Expander.Content>
</Expander>
答案 0 :(得分:2)
某些控件为其使用的控件定义了自己的Styles
。例如,Expander
的默认模板为ControlTemplate
定义了ToggleButton
并将其设置为这样(我不想复制整个默认样式,因为它很长):
<ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
Content="{TemplateBinding Header}" ... Style="{StaticResource ExpanderDownHeaderStyle}" ... />
<Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/>
<ContentPresenter Grid.Column="1" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
因为这是一个本地值,所以它优先于定义为资源的样式 正如dkozl在评论中提到的那样,检查Dependency Property Setting Precedence List以找出哪个优先于什么。