我想在点击时减轻按钮背景。所以我做了以下事情:
<converter:ColorLightConverter x:Key="colorLightConverter" />
...
<Style BasedOn="{StaticResource default}" TargetType="{x:Type controls:Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:Button}">
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{Binding Path=Background.Color, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource colorLightConverter}}" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
<Border Background="{TemplateBinding Background}"
BorderBrush="Transparent"
BorderThickness="0">
...
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
转化器:
class ColorLightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Color color = (Color)value;
System.Drawing.Color lightColor = ControlPaint.Light(System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B));
return Color.FromArgb(lightColor.A, lightColor.R, lightColor.G, lightColor.B);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
但单击按钮时未调用转换器。我认为绑定有什么问题,但我看不出错误......
你能帮助我吗?
也许我完全错了。我基本上想要做的事情:单击按钮时,取出当前背景颜色并使其变亮。不多......
我尝试了以下内容:
稍微更改了绑定:
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{Binding Path=Background.Color, RelativeSource={RelativeSource Self}, Converter={StaticResource colorLightConverter}}" />
</Trigger>
更改了转换器(现在它返回一个SolidColorBrush):
class ColorLightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Color color = (Color)value;
System.Drawing.Color lightColor = ControlPaint.Light(System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B));
return new SolidColorBrush(Color.FromArgb(lightColor.A, lightColor.R, lightColor.G, lightColor.B));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
现在调用转换器,但是一次又一次地调用它,因此几秒钟后抛出stackoverflow异常。这个无限循环来自哪里?我现在真的有点困惑......
答案 0 :(得分:1)
您不应该在WPF上使用System.Drawing.Color。请改用System.Windows.Media.Color。另一个重要的事情是ControlTemplate.Triggers中的Setter不必使用RelativeSource TemplatedParent来引用控件。只是:
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="YourLightColor"/>
</Trigger>
并保持其余部分相同。现在,如果您需要指定自定义逻辑(例如转换器,只需将转换器放在该设置器中。
编辑: 无限循环来自于你绑定到Background.Color,然后设置背景,它会触发一个属性更改通知到WPF属性系统,这反过来导致Binding被刷新,等等......我想你可以通过将绑定模式设置为= OneTime
来解决这个问题答案 1 :(得分:0)
我使用了Button的以下样式。它可能对你有所帮助。
<Style TargetType="{x:Type Button}">
<!-- General for all buttons -->
<Setter Property="Foreground"
Value="Azure" />
<Setter Property="FontFamily"
Value="Verdana" />
<Setter Property="FontSize"
Value="12" />
<Setter Property="FontWeight"
Value="Bold" />
<Setter Property="Margin"
Value="4,4,4,4"></Setter>
<Setter Property="VerticalAlignment"
Value="Center"></Setter>
<Setter Property="Background">
<Setter.Value>
<RadialGradientBrush>
<GradientStop Color="#145082"
Offset="0" />
<GradientStop Color="Black"
Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="GelBackground"
Opacity="1"
RadiusX="9"
RadiusY="9"
Fill="{TemplateBinding Background}"></Rectangle>
<Rectangle x:Name="GelShine"
Margin="2,2,2,0"
VerticalAlignment="Top"
RadiusX="4"
RadiusY="4"
Opacity=".8"
Stroke="Transparent"
Height="15">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientStop Color="#ccffffff"
Offset="0" />
<GradientStop Color="Transparent"
Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter Margin="10,0,10,0"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Foreground"
Value="White" />
<Setter Property="FontSize"
Value="12" />
<Setter Property="Rectangle.Fill"
TargetName="GelBackground">
<Setter.Value>
<RadialGradientBrush>
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="Tomato"
Offset="0" />
<GradientStop Color="Black"
Offset="1" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed"
Value="true">
<Setter Property="Foreground"
Value="Black" />
<Setter Property="Fill"
TargetName="GelBackground">
<Setter.Value>
<RadialGradientBrush>
<GradientStop Color="#ffcc00"
Offset="0" />
<GradientStop Color="#cc9900"
Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="Black" />
<Setter Property="Fill"
TargetName="GelBackground">
<Setter.Value>
<RadialGradientBrush>
<GradientStop Color="White"
Offset="0" />
<GradientStop Color="#333333"
Offset=".4" />
<GradientStop Color="#111111"
Offset=".6" />
<GradientStop Color="#000000"
Offset=".7" />
<GradientStop Color="#000000"
Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
答案 2 :(得分:0)
问题在于背景,我不确切知道所有属性的原因,背景总是以这种方式行事,但如果你设置模板而不是背景,问题就解决了:
<Style TargetType="{x:Type controls:Button}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:Button}">
<Border>
<Border.Background>
<SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Background.Color, Converter={StaticResource colorLightConverter}}"/>
</Border.Background>
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Setter Property="Template">
<Setter.Value.../>
</Setter>
</Style>