I'm using MahApps framework and I have the style (see How to change tile background on mouse over in WPF?) for highlighting a tile on 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>
The color converter code is:
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));
}
}
Basically, I want to be able to:
My code works only if I set the non-highlighted background color in the style (in this case, "Purple"). Without setting this color in the style (removing the first line), the code only works with the default blue background color of the tile (if I set the color in MainWindow.xaml, then the Converter isn't even triggered, which I verified using a breakpoint). Initially I used this binding, but does not work:
<Setter Property="Background" Value="{Binding Path=Background.Color, RelativeSource={RelativeSource Self}}" />
What am I doing wrong? Or is it what I'm asking actually achievable?
I suggest you to override the style for the Tile and use your converter at the ControlTemplate triggers.
The following XAML source works with the latest source of MahApps, which is also available vie NuGet (pre-release).
<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>
Hope that helps!