如何 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));
}
}
基本上,我希望能够:
- 在设计器视图中设置磁贴的背景;完成
- 然后将此样式应用于图块;完成
- 在运行时,在 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>
希望对您有所帮助!
我正在使用 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));
}
}
基本上,我希望能够:
- 在设计器视图中设置磁贴的背景;完成
- 然后将此样式应用于图块;完成
- 在运行时,在 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>
希望对您有所帮助!