每次使用转换器绑定时,按钮单击可以减轻背景颜色

时间:2012-10-29 16:58:46

标签: c# wpf xaml binding converter

我想在点击时减轻按钮背景。所以我做了以下事情:

<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();
        }
    }

但单击按钮时未调用转换器。我认为绑定有什么问题,但我看不出错误......

你能帮助我吗?

也许我完全错了。我基本上想要做的事情:单击按钮时,取出当前背景颜色并使其变亮。不多......

更新1:

我尝试了以下内容:

稍微更改了绑定:

<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异常。这个无限循环来自哪里?我现在真的有点困惑......

3 个答案:

答案 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>