如何 Lighten/Darken 在鼠标悬停时平铺背景颜色?

How To Lighten/Darken Tile Background Color On Mouse Over?

我正在使用 MahApps 框架,并且我具有在 MouseOver 上突出显示图块的样式(请参阅 )。

 <local:ColorConverter x:Key="colorConverter" />
 <Style x:Key="highlightedTile" TargetType="mah:Tile">
     <Setter Property="Background" Value="Purple" />
     <Style.Triggers>
         <Trigger Property="IsMouseOver" Value="True">
             <Setter Property="Background" Value="{Binding Path=Background, RelativeSource={RelativeSource Self}, Converter={StaticResource colorConverter}, Mode=OneTime, FallbackValue=red}" />
         </Trigger>
     </Style.Triggers>
 </Style>

颜色转换器代码为:

class ColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        byte[] temp = StringToByteArray(value.ToString().Substring(1, 8)); // Remove #
        Color color = Color.FromArgb(temp[0], temp[1], temp[2], temp[3]);
        System.Drawing.Color darkColor = System.Windows.Forms.ControlPaint.Dark(System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B), 0.1f);
        return new SolidColorBrush(Color.FromArgb(darkColor.A, darkColor.R, darkColor.G, darkColor.B));
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public static byte[] StringToByteArray(string hex)
    {
        if (hex.Length % 2 == 1)
            throw new Exception("The binary key cannot have an odd number of digits");

        byte[] arr = new byte[hex.Length >> 1];

        for (int i = 0; i < hex.Length >> 1; ++i)
        {
            arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
        }

        return arr;
    }

    public static int GetHexVal(char hex)
    {
        int val = (int)hex;
        //For uppercase A-F letters:
        return val - (val < 58 ? 48 : 55);
        //For lowercase a-f letters:
        //return val - (val < 58 ? 48 : 87);
        //Or the two combined, but a bit slower:
        //return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
    }
}

基本上,我希望能够:

  1. 在设计器视图中设置磁贴的背景;完成
  2. 然后将此样式应用于图块;完成
  3. 在运行时,在 MouseOver 上看到它的背景变暗(突出显示图块)并且 return 到初始颜色当鼠标存在图块时(宿主控件的背景不应该影响这个逻辑)。 需要帮助

只有在样式中设置非高亮背景色(在本例中为 "Purple")时,我的代码才有效。如果不在样式中设置此颜色(删除第一行),代码仅适用于图块的默认蓝色背景颜色(如果我在 MainWindow.xaml 中设置颜色,则甚至不会触发转换器,这我使用断点进行了验证)。最初我使用此绑定,但不起作用:

<Setter Property="Background" Value="{Binding Path=Background.Color, RelativeSource={RelativeSource Self}}" />

我做错了什么?还是我所要求的实际上可以实现?

我建议您重写 Tile 的样式并在 ControlTemplate 触发器中使用您的转换器。

以下 XAML 源代码适用于 MahApps 的最新源代码,也可通过 NuGet(预发布)获得。

<local:ColorConverter x:Key="colorConverter" />
<Style x:Key="CustomTileStyle" BasedOn="{StaticResource {x:Type controls:Tile}}" TargetType="{x:Type controls:Tile}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:Tile">
                <Grid>
                    <Border x:Name="PART_Border"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                        <Grid>
                            <StackPanel HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                        Orientation="Horizontal">
                                <ContentPresenter RecognizesAccessKey="True" />
                                <TextBlock VerticalAlignment="Center"
                                            FontSize="{TemplateBinding CountFontSize}"
                                            Text="{TemplateBinding Count}" />
                            </StackPanel>
                            <Label HorizontalAlignment="{TemplateBinding HorizontalTitleAlignment}"
                                    VerticalAlignment="{TemplateBinding VerticalTitleAlignment}"
                                    Foreground="{TemplateBinding Foreground}">
                                <AccessText Margin="3"
                                            Foreground="{TemplateBinding Foreground}"
                                            FontSize="{TemplateBinding TitleFontSize}"
                                            Text="{TemplateBinding Title}"
                                            TextWrapping="Wrap" />
                            </Label>
                        </Grid>
                    </Border>
                    <Border x:Name="PART_HoverBorder"
                            BorderBrush="{TemplateBinding controls:ControlsHelper.MouseOverBorderBrush}"
                            BorderThickness="2"
                            Opacity="0"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="PART_Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background, Mode=OneWay, Converter={StaticResource colorConverter}}" />
                    </Trigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=(controls:ControlsHelper.MouseOverBorderBrush), Mode=OneWay, Converter={x:Static converters:IsNullConverter.Instance}}" Value="False" />
                            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver, Mode=OneWay}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter TargetName="PART_HoverBorder" Property="Opacity" Value="0.6" />
                    </MultiDataTrigger>
                    <Trigger Property="Button.IsPressed" Value="True">
                        <Setter Property="RenderTransform">
                            <Setter.Value>
                                <ScaleTransform CenterX="0.5"
                                                CenterY="0.5"
                                                ScaleX="0.98"
                                                ScaleY="0.98" />
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Opacity" Value=".55" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

希望对您有所帮助!