试图理解视觉树内部的样式覆盖如何工作时,我有点困惑。
我有两个示例 - 第一个示例定义 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>
最佳答案
某些控件为其使用的控件定义了自己的样式
。例如 Expander
的默认模板为 ToggleButton
定义了一个 ControlTemplate
并像这样设置它(我不想在这里复制整个默认样式因为它很长):
<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找出哪个优先于哪个。
关于wpf - 为什么某些 WPF 自定义样式元素被忽略,而其他元素却被保留?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33221268/