0

I have an attached property that I would like to bind to in my button's ControlTemplate VisualStateManager.

Below is the code for the property and the XAML for the button style. I have no errors or warnings, but the button doesn't change colors when I mouse over it or when I press it.

What's wrong with this? I've looked at the following examples and they haven't worked so far:

How to use Attached property within a style?

Problem reading AttachedProperty in ControlTemplate

Here's the property:

using System.Windows;
using System.Windows.Media;

namespace company.project.Utilities.AttachedBehaviors
{
    public class Attached : DependencyObject
    {
        // Attached properties...
        #region MouseOverColor Property

        public static readonly DependencyProperty MouseOverColorProperty = DependencyProperty.RegisterAttached(
              "MouseOverColor",
              typeof(Color),
              typeof(Attached)
            );

        public static void SetMouseOverColor(UIElement element, Color value)
        {
            element.SetValue(MouseOverColorProperty, value);
        }

        public static Color GetMouseOverColor(UIElement element)
        {
            return (Color)element.GetValue(MouseOverColorProperty);
        }

        #endregion

        #region PressedColor Property

        public static readonly DependencyProperty PressedColorProperty = DependencyProperty.RegisterAttached(
              "PressedColor",
              typeof(Color),
              typeof(Attached)
            );

        public static void SetPressedColor(UIElement element, Color value)
        {
            element.SetValue(PressedColorProperty, value);
        }

        public static Color GetPressedColor(UIElement element)
        {
            return (Color)element.GetValue(PressedColorProperty);
        }

        #endregion
    }
}

Here's the style:

xmlns:attached="clr-namespace:company.project.Utilities.AttachedBehaviors;assembly=company.project.Utilities"

<Style x:Key="DialogButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource StandardButtonStyle}">
    <Setter Property="Background" Value="{StaticResource ElectroTekGrayBrush}" />
    <Setter Property="attached:Attached.MouseOverColor" Value="{StaticResource ElectroTekGreen}" />
    <Setter Property="attached:Attached.PressedColor" Value="{StaticResource ElectroTekLightGray}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Border" To="{Binding Path=(attached:Attached.MouseOverColor), RelativeSource={RelativeSource AncestorType=Button}}" Duration="0" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Border" To="{Binding Path=(attached:Attached.PressedColor), RelativeSource={RelativeSource AncestorType=Button}}" Duration="0" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border Name="Border" Background="{TemplateBinding Background}" CornerRadius="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight, Converter={StaticResource MathConverter}, ConverterParameter=(@VALUE/2)}" IsHitTestVisible="True">
                        <Grid>
                            <TextBlock x:Name="TextBlock" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="15" />
                        </Grid>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="TextBlock" Property="Cursor" Value="Hand" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Here's the button:

<Button Style="{StaticResource DialogButton}" />
Community
  • 1
  • 1
Matt Becker
  • 2,338
  • 1
  • 28
  • 36

1 Answers1

0

Alright, I assumed that @King King was correct about the To and From properties and just implemented the same functionality using triggers. Here's the style if anybody needs it.

<Style x:Key="DialogButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource StandardButtonStyle}">
    <Setter Property="Background" Value="{StaticResource ElectroTekGrayBrush}" />
    <Setter Property="attached:Attached.MouseOverColor" Value="{StaticResource ElectroTekGreen}" />
    <Setter Property="attached:Attached.PressedColor" Value="{StaticResource ElectroTekOrange}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <Border Name="border" Background="{TemplateBinding Background}" CornerRadius="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight, Converter={StaticResource MathConverter}, ConverterParameter=(@VALUE/2)}" IsHitTestVisible="True" Cursor="Hand">
                        <TextBlock x:Name="TextBlock" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="15" Cursor="Hand" />
                    </Border>
                </Grid>
                <ControlTemplate.Resources>
                    <SolidColorBrush x:Key="MouseOverBrush" Color="{Binding Path=(attached:Attached.MouseOverColor), RelativeSource={RelativeSource AncestorType=Button}}" />
                    <SolidColorBrush x:Key="PressedBrush" Color="{Binding Path=(attached:Attached.PressedColor), RelativeSource={RelativeSource AncestorType=Button}}" />
                </ControlTemplate.Resources>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True" SourceName="border">
                        <Setter Property="Background" Value="{StaticResource MouseOverBrush}" TargetName="border" />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" Value="{StaticResource PressedBrush}" TargetName="border" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Matt Becker
  • 2,338
  • 1
  • 28
  • 36
  • 1
    That's good as long as you don't use the Storyboard for real animations, i. e. set the Duration to 0. I need this with an animation so I can't use triggers in my case. I've read elsewhere that animations must be frozen and therefore cannot use bindings. – ygoe Jun 17 '16 at 22:50