假设我的窗口中有3个按钮:
<Button Content="Green Button" Background="LimeGreen" Style="{StaticResource ButtonStyle}" Margin="0,0,0,10" />
<Button Content="Red Button" Background="Red" Style="{StaticResource ButtonStyle}" Margin="0,0,0,10" />
<Button Content="Hex Button" Background="#FF32CD32" Style="{StaticResource ButtonStyle}" />
在app.xaml中,我创建了一个将被所有按钮使用的样式:
<Application.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type ButtonBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border Name="border"
BorderThickness="1.5"
Padding="{TemplateBinding Padding}"
BorderBrush="Black"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Opacity" Value="0.9" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="Background" Value="Red" />
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="DarkOrange" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="Background" Value="LimeGreen" />
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="Chartreuse" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
对于前两个按钮,一切都很完美。但是,当我尝试单击第三个按钮时,没有任何反应。 即使我添加了另一个条件为“Background value =”#FF32CD32“(它应该与LimeGreen相同)的多重组合,它也不会改变任何内容。
十六进制值是否适用于触发器?
答案 0 :(得分:0)
嗯,在获得WPF的更多经验之后,我决定再给它一次。答案几乎立刻就来了......
问题是,条件中提供的值被读作颜色。单独的XAML无法解析其RGB表示。让我们看看例子:
如果背景颜色为红色(已在“颜色/画笔”枚举中定义),则正在正确读取值。但是,如果提供的值是#FFABCDEF,它也是一种颜色,但它没有被定义为标准颜色。对于XAML,它只是一个普通的字符串。因此,通过提供十六进制值而不是预定义的枚举,触发器将失败。
解决方法是创建自定义转换器。它会将颜色值转换为相应的字符串表示形式。然后,当我们检查条件中的值时,转换器将为我们提供有效的字符串。
首先我创建了转换器,它返回有效的十六进制颜色值:
public class ColorToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Color c = (value as SolidColorBrush).Color;
return c.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后,在您的样式文件中,包含已创建转换器的命名空间:
xmlns:conv="clr-namespace:ButtonTest.Converters"
在样式文件资源中(在这种情况下,它只是App.xaml):
<conv:ColorToStringConverter x:Key="ColorToStringConverter" />
最后,触发器:
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Opacity" Value="0.9" />
</Trigger>
<!-- Custom colors handling there -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsPressed}" Value="True" />
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Background, Converter={StaticResource ColorToStringConverter}}" Value="#FF32CD32" />
</MultiDataTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="Chartreuse" />
</MultiDataTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="Background" Value="Red" />
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="DarkOrange" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="Background" Value="LimeGreen" />
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="Chartreuse" />
</MultiTrigger>
密切关注触发器优先级:应在标准颜色之前声明hex值。在我的例子中,#FF32CD32与LimeGreen相同,所以如果我把它放在最后,它将覆盖标准触发器。