How to change tile background on mouse over in WPF

2019-09-20 06:05发布

问题:

Using the code provided in this post:

lighten background color on button click per binding with converter

I have written the following code to change the background of a MahApps Tile on MouseOver:

<local:ColorLightConverter x:Key="colorLightConverter" />
    <Style x:Key="aaa" TargetType="mah:Tile">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="{Binding Path=Background.Color, RelativeSource={RelativeSource TemplatedParent}, Mode=OneTime, Converter={StaticResource colorLightConverter}}" />
            </Trigger>
        </Style.Triggers>
    </Style>

The color light converter is the same as written in the post mentioned and the style is used on the Mahapps Metro Tile. The code does not work, because the tile flickers on MouseOver. Also, placing a breakpoint inside the converter, I saw that it is not reached.

What am I doing wrong?

回答1:

I could reproduce the problem with the Tile control. It never enters the Converter code because TemplatedParent is null. When I changed the RelativeSource to AncestorType={x:Type StackPanel} as it was in my case, the flickering went away and the breakpoint in the converter was reached. You can check if this is the case with you by adding to the Binding FallbackValue=Red in which case the color on mouse over will be Red for a faulty binding.

Here is my working XAML:

<Window.Resources>
        <local:ColorLightConverter x:Key="colorLightConverter" />
        <Style x:Key="aaa" TargetType="{x:Type Control}">
            <Setter Property="Background" Value="White"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="{Binding Path=Background.Color, RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}, Converter={StaticResource colorLightConverter},FallbackValue=Red}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel Background="DarkGoldenrod">
        <mah:Tile Title="Hello!" Style="{StaticResource aaa}" 
                    TiltFactor="2"
                    Width="100" Height="100" 
                    Count="1" x:Name="tile">
        </mah:Tile>
        <TextBox Width="100" Height="100" Style="{StaticResource aaa}">Test</TextBox>
    </StackPanel>


回答2:

OK. So this is the MainWindow.xaml:

<mah:MetroWindow 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:NQR_GUI_WPF"
    xmlns:prop="clr-namespace:NQR_GUI_WPF.Properties"
    xmlns:Custom="http://metro.mahapps.com/winfx/xaml/controls" 
    x:Class="NQR_GUI_WPF.MainWindow"
    xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
    mc:Ignorable="d" Height="600" Width="800" ResizeMode="CanResizeWithGrip" WindowStartupLocation="CenterScreen" TitlebarHeight="28"
    GlowBrush="{DynamicResource AccentColorBrush}" ShowIconOnTitleBar="False" Icon="Pictures/icon.ico"
>
<Window.Resources>
    <local:ColorLightConverter x:Key="colorLightConverter" />
    <Style x:Key="aaa" TargetType="{x:Type Control}">
        <Setter Property="Background" Value="White"/>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="{Binding Path=Background.Color, Mode=OneTime, RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}, Converter={StaticResource colorLightConverter}}" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<StackPanel Background="DarkGoldenrod">
    <mah:Tile Title="Hello!" Style="{StaticResource aaa}"
                TiltFactor="2"
                Width="100" Height="100" 
                Count="1" x:Name="tile">
    </mah:Tile>
    <TextBox Width="100" Height="100" Style="{StaticResource aaa}">Test</TextBox>
</StackPanel>

This is the App.xaml

<Application x:Class="NQR_GUI_WPF.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:NQR_GUI_WPF"
         xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
         StartupUri="MainWindow.xaml">
<Application.Resources>
    <ResourceDictionary>
        <BitmapImage x:Key="settingsIcon" UriSource="Pictures/settings1_unpressed.png" />
        <ResourceDictionary.MergedDictionaries>
            <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
            <!-- Accent and AppTheme setting -->
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

This is the color converter code:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
         Color color = (Color)value;
         System.Drawing.Color darkColor = System.Windows.Forms.ControlPaint.Dark(System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B), 0.1f);
         return System.Drawing.Color.FromArgb(darkColor.A, darkColor.R, darkColor.G, darkColor.B);
     }

I am using MahApps 1.2.4.0.