更改样式控件中的控件模板的一部分?
Change part of controltemplate in styled controls?
我已经使用 ControlTemplate 自定义了 ToggleButton 控件,如下所示:
<StackPanel>
<StackPanel.Resources>
<Style x:Key="OptionBarButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="18,12,18,12" Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="DarkBlue" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="SkyBlue" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="#88000000" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="#F0000000" />
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<ToggleButton Style="{StaticResource OptionBarButton}">
<Image Source="../Assets/icons/action.png" Height="26" RenderOptions.BitmapScalingMode="Fant" />
</ToggleButton>
<ToggleButton Style="{StaticResource OptionBarButton}">
<Image Source="../Assets/icons/action2.png" Height="26" RenderOptions.BitmapScalingMode="Fant" />
</ToggleButton>
</StackPanel>
这很好用,但是我现在想更改某些样式控件中模板的某些部分,即 IsChecked 颜色状态 (SkyBlue/DarkBlue)。
是否可以在使用模板时修改/传递这些颜色in/to模板?我知道我可以使用附加属性 or/and subclass ToggleButton class (向其添加依赖属性),但我想知道是否有更惯用的方法来解决这个问题,也许只有 xaml。对于这样一个简单的用例,必须在 C# 中编写自定义代码似乎有点矫枉过正?
不幸的是,ControlTemplates 是一个孤注一掷的东西。如果您想更改您在其中引用的颜色,则必须切换模板。我认为在模板中 引用资源 不适合您。
我将为 OptionBarButton 中的每种可变颜色创建依赖属性。
据我所知,如果没有代码,没有简单的方法可以做到这一点,但如果您真的想要 - 您可以以某种方式利用动态资源。通常动态资源用于在运行时更改所有控件实例的外观。您从模板中引用动态资源,然后更改该资源,所有控件都会反映此更改。在这种情况下,这可能不是您所需要的,因为您想要更改 "some parts of the template in some of the styled controls"。您仍然可以这样做:
<!-- default checked and over color -->
<SolidColorBrush x:Key="TgCheckedAndOver" Color="DarkBlue" />
<!-- default checked color -->
<SolidColorBrush x:Key="TgChecked" Color="SkyBlue" />
<Style
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="18,12,18,12"
Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked"
Value="True" />
<Condition Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background"
Value="{DynamicResource TgCheckedAndOver}" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked"
Value="True" />
<Condition Property="IsMouseOver"
Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background"
Value="{DynamicResource TgChecked}" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked"
Value="False" />
<Condition Property="IsMouseOver"
Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background"
Value="#88000000" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked"
Value="False" />
<Condition Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background"
Value="#F0000000" />
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这是动态资源的常规使用。现在,当您只想为特定控件更改外观时,您可以这样做:
<ToggleButton>
<ToggleButton.Resources>
<!-- override default resources -->
<SolidColorBrush x:Key="TgChecked" Color="Yellow" />
<SolidColorBrush x:Key="TgCheckedAndOver"
Color="Green" />
</ToggleButton.Resources>
<Image Source="../Assets/icons/action.png" Height="26" RenderOptions.BitmapScalingMode="Fant" />
</ToggleButton>
因为您将具有相同键 "closer" 的新资源放置到控件中 - 模板将使用它们而不是默认的,并且只有这个特定的控件会这样做,而不是所有的。
我已经使用 ControlTemplate 自定义了 ToggleButton 控件,如下所示:
<StackPanel>
<StackPanel.Resources>
<Style x:Key="OptionBarButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="18,12,18,12" Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="DarkBlue" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="SkyBlue" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="#88000000" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="#F0000000" />
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<ToggleButton Style="{StaticResource OptionBarButton}">
<Image Source="../Assets/icons/action.png" Height="26" RenderOptions.BitmapScalingMode="Fant" />
</ToggleButton>
<ToggleButton Style="{StaticResource OptionBarButton}">
<Image Source="../Assets/icons/action2.png" Height="26" RenderOptions.BitmapScalingMode="Fant" />
</ToggleButton>
</StackPanel>
这很好用,但是我现在想更改某些样式控件中模板的某些部分,即 IsChecked 颜色状态 (SkyBlue/DarkBlue)。
是否可以在使用模板时修改/传递这些颜色in/to模板?我知道我可以使用附加属性 or/and subclass ToggleButton class (向其添加依赖属性),但我想知道是否有更惯用的方法来解决这个问题,也许只有 xaml。对于这样一个简单的用例,必须在 C# 中编写自定义代码似乎有点矫枉过正?
不幸的是,ControlTemplates 是一个孤注一掷的东西。如果您想更改您在其中引用的颜色,则必须切换模板。我认为在模板中 引用资源 不适合您。
我将为 OptionBarButton 中的每种可变颜色创建依赖属性。
据我所知,如果没有代码,没有简单的方法可以做到这一点,但如果您真的想要 - 您可以以某种方式利用动态资源。通常动态资源用于在运行时更改所有控件实例的外观。您从模板中引用动态资源,然后更改该资源,所有控件都会反映此更改。在这种情况下,这可能不是您所需要的,因为您想要更改 "some parts of the template in some of the styled controls"。您仍然可以这样做:
<!-- default checked and over color -->
<SolidColorBrush x:Key="TgCheckedAndOver" Color="DarkBlue" />
<!-- default checked color -->
<SolidColorBrush x:Key="TgChecked" Color="SkyBlue" />
<Style
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="18,12,18,12"
Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked"
Value="True" />
<Condition Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background"
Value="{DynamicResource TgCheckedAndOver}" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked"
Value="True" />
<Condition Property="IsMouseOver"
Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background"
Value="{DynamicResource TgChecked}" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked"
Value="False" />
<Condition Property="IsMouseOver"
Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background"
Value="#88000000" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked"
Value="False" />
<Condition Property="IsMouseOver"
Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background"
Value="#F0000000" />
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这是动态资源的常规使用。现在,当您只想为特定控件更改外观时,您可以这样做:
<ToggleButton>
<ToggleButton.Resources>
<!-- override default resources -->
<SolidColorBrush x:Key="TgChecked" Color="Yellow" />
<SolidColorBrush x:Key="TgCheckedAndOver"
Color="Green" />
</ToggleButton.Resources>
<Image Source="../Assets/icons/action.png" Height="26" RenderOptions.BitmapScalingMode="Fant" />
</ToggleButton>
因为您将具有相同键 "closer" 的新资源放置到控件中 - 模板将使用它们而不是默认的,并且只有这个特定的控件会这样做,而不是所有的。