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>
我想在 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>