0

To easily change the template-specific brushes of a button without directly changing the template, I decided to make a DependencyProperty that will bind to a template-specific brush. That way, I can change this brush just as easy as changing any other regular property. However, after implementing this DependencyProperty, I encountered an error: "Name "ExtensionClass" does not exist in namespace "clr-namespace:extensions"." What causes this error?

XAML:

<ResourceDictionary xmlns:ext="clr-namespace:Extensions"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <ControlTemplate x:Key="ButtonBaseControlTemplate1" TargetType="{x:Type ButtonBase}">
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" TargetName="border" Value="{TemplateBinding Property=ext:ExtensionsClass.MouseOverBackground}"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</ResourceDictionary>

C#:

namespace Extensions {
    public class ExtensionsClass {
        public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(Button));

        public static void SetMouseOverBackground(UIElement element, Brush value) {
            element.SetValue(MouseOverBackgroundProperty, value);
        }

        public static Brush GetMouseOverBackground(UIElement element) {
            return (Brush)element.GetValue(MouseOverBackgroundProperty);
        }
    }
}

1 Answers1

0

In addition to the problem with the Binding, which is covered in the answer to the duplicate question, you also have to be aware that you are declaring an attached property, which has to be registered with the RegisterAttached method.

Besides that, in both the Register and the RegisterAttached methods, the third argument has to be the type that declares the property, not the type of element where you intend to set the property, i.e. typeof(ExtensionsClass) here.

public static class ExtensionsClass
{
    public static readonly DependencyProperty MouseOverBackgroundProperty =
        DependencyProperty.RegisterAttached(
             "MouseOverBackground",
             typeof(Brush), 
             typeof(ExtensionsClass),
             null);

    public static void SetMouseOverBackground(UIElement element, Brush value)
    {
        element.SetValue(MouseOverBackgroundProperty, value);
    }

    public static Brush GetMouseOverBackground(UIElement element)
    {
        return (Brush)element.GetValue(MouseOverBackgroundProperty);
    }
}

You bind to an attached property by means of a Binding Path with parentheses:

<Setter
    Property="Background"
    TargetName="border"
    Value="{Binding Path=(ext:ExtensionsClass.MouseOverBackground),
            RelativeSource={RelativeSource TemplatedParent}}"/>
       
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • 1. Why an attached property? 2. Wouldn't Binding be slower than TemplateBinding? – snailatspace Jul 17 '21 at 10:32
  • A regular dependency property is declared in a class that derives from DependencyObject and can only be set on instances of the class that declares the property, or classes derived from that class. – Clemens Jul 17 '21 at 10:34
  • 2. TemplateBinding won't work. – Clemens Jul 17 '21 at 10:34
  • You mean to set it in a Style? Sure, like any other property: https://stackoverflow.com/q/25595272/1136211 – Clemens Jul 18 '21 at 09:19