views:

287

answers:

1

I've run into an odd problem with attached properties where when I assign the property name in the call to RegisterAttached and name properly for the name of the attached property (say TranslateProperty and "Translate") the code for the attached property implementation doesn't fire. Just doesn't get called. If I change the string name to anything other than Translate (say "Translate_") the code gets called just fine.

Here's the implementation:

public class TranslateExtension : DependencyObject {

public static readonly DependencyProperty TranslateProperty =
    DependencyProperty.RegisterAttached("Translate_",
                                        typeof(bool),
                                        typeof(TranslateExtension),
                                        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));

public static void SetTranslate(UIElement element, bool value)
    {
        AssignKeys(element);
        element.SetValue(TranslateProperty, value);
    }
    public static bool GetTranslate(UIElement element)
    {
        return (bool)element.GetValue(TranslateProperty);
    }

    public bool Translate
    {
        set { base.SetValue( TranslateProperty,  value); }
    }
   ...
}

The above actually works because the property in the string is Translate_. If I change the string value to "Translate" it failed.

I have 2 other attached properties in the same class and they exhibit exactly the same behavior - same name as the AttachedProperty and they don't get called. Name it something else and it works.

I'm not sure what's going on here. My code is actually working with the invalid names, but I don't understand why, and more importantly I'm not sure if this wrong naming causes any side effects.

Can anybody see whether I'm overlooking something painfully obvious? I've revisited a few examples in articles of AttachedProperties and I don't see those implementations using special names - they always name the string property the same as the attached properties.

+2  A: 

You shouldn't put extra code in your SetTranslate since it won't get called. From MSDN here:

Implications for Custom Dependency Properties

Because the current WPF implementation of the XAML processor behavior for property setting bypasses the wrappers entirely, you should not put any additional logic into the set definitions of the wrapper for your custom dependency property. If you put such logic in the set definition, then the logic will not be executed when the property is set in XAML rather than in code.

Similarly, other aspects of the XAML processor that obtain property values from XAML processing also use GetValue rather than using the wrapper. Therefore, you should also avoid any additional implementation in the get definition beyond the GetValue call.

Instead, add a PropertyChangedCallback to your FrameworkPropertyMetadata.

micahtan
Yup that's exactly it! Adding the PropertyChangedCallback() to the new FrameworkMetaData() constructor did the trick. Still I wonder why having an invalid name (like "Translate_") would trigger the SetTranslate method to get called. This is really odd behavior.
Rick Strahl