TemplateBinding 与 IValueConverter

TemplateBinding with IValueConverter

我想在 WPF 项目中生成自定义按钮。我希望按钮以不透明度降低的方式更改其背景颜色。

因此我有一个带有默认按钮样式的资源字典:

<Style x:Key="DefaultStyle" TargetType="{x:Type Button}">
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="{Binding Path=Background, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource OpacityConverter}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="GreenButton" TargetType="{x:Type Button}" BasedOn="{StaticResource DefaultStyle}">
        <Setter Property="Background" Value="{StaticResource Green}"/>
        <Setter Property="Foreground" Value="Black"/>
</Style>

使用我的自定义转换器:

<conv:OpacityConverter x:Key="OpacityConverter"/>

xmlns:conv="clr-namespace:ProjectNamespace.Converter":

中实现
public class OpacityConverter : IValueConverter
{

    public OpacityConverter()
    {

    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        SolidColorBrush brush = ((SolidColorBrush)value).Clone();
        brush.Opacity = 0.5;
        return brush;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        SolidColorBrush brush = ((SolidColorBrush)value).Clone();
        brush.Opacity = 1;
        return brush;
    }
}

在我的 Window 中,我使用这样的按钮:

<Button Grid.Row="1" Grid.Column="2" 
        Style="{StaticResource GreenButton}">
   <TextBlock Text="neues Projekt anlegen" TextWrapping="Wrap" TextAlignment="Center"/>
</Button>

按钮看起来像这样:

我想要这样的外观(如果 IsMouseOver == True):

但是现在,随着 IsMouseOver == True 启动,背景变成全白,按钮看起来像这样:

我错过了什么?

由于您没有在 Trigger 中为 Setter 指定 TargetName,它隐式引用 Button 并导致循环引用。要修复它,请命名 Border 并在 Setter.

中指定该名称
<ControlTemplate TargetType="Button">
    <Border x:Name="border"
            Background="{TemplateBinding Background}">
        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter TargetName="border"
                    Property="Background"
                    Value="{Binding Background, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource OpacityConverter}}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>