13

I'm trying to add a PropertyChangedCallback to UIElement.RenderTransformOriginProperty. An exception is thrown when I try to override the PropertyMetadata.

I have searched MSDN and Google, and all I have been able to come up with is this. DependencyPropertyDescriptor.AddValueChanged is suggested at some point in that post, but that won't solve my problem since this is not a per-instance callback.

I don't understand what this exception means at all. Does anyone know what I am doing wrong?

public class foo : FrameworkElement
{
    private static void Origin_Changed( DependencyObject d,
                                        DependencyPropertyChangedEventArgs e)
    { }

    static foo()
    {
        PropertyMetadata OriginalMetaData =
            UIElement.RenderTransformOriginProperty.GetMetadata(
                typeof(FrameworkElement));



/*An exception is thrown when this line is executed:
 "Cannot change property metadata after it has been associated with a property"*/
        OriginalMetaData.PropertyChangedCallback +=
            new PropertyChangedCallback(Origin_Changed);



        UIElement.RenderTransformOriginProperty.OverrideMetadata(
            typeof(foo), OriginalMetaData);
    }
}
Giffyguy
  • 20,378
  • 34
  • 97
  • 168

1 Answers1

26

WPF will merge the property metadata for you when you call OverrideMetadata, no need to pass it the original Metadata object. So all you have to do is

UIElement.RenderTransformOriginProperty.OverrideMetadata(typeof(foo), new PropertyMetadata(new PropertyChangedCallback(Origin_Changed)));

One thing to be aware of is sometimes the code above throws an exception. The two cases where that happens are

1. The original metadata is a subclass of PropertyMetadata - I have seen FrameworkPropertyMetadata and UIPropertyMetadata. You just have to use the appropriate one in each case.

2. The dependency property is read only and you can't do anything about it.

Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
  • That's perfect! Thanks! I tend to assume the framework isn't going to do that kind of work for me automatically. I guess it's just the ocupational hazard of being a low-level engineer in the era of high-level dominance ... – Giffyguy Aug 21 '09 at 04:42
  • Hehe, I can sympathize with that. I spent countless hours trying to bend WPF from a Win32 programmer perspective when I couldn't work out the "cosher" WPF way. – Igor Zevaka Aug 21 '09 at 04:50
  • Regarding your edit: Oh dang, that throws me off a little bit - I need to listen for changes to some read-only FrameworkElement dependency-properties, as well... This being the case, what would you suggest? I really, REALLY don't want to try to implement it using AddValueChanged on every instance of my class. Although, I guess I wouldn't mind, as long as it doesn't have any performance hit - versus PropertyChangedCallback. Alas, this needs to be efficient, by all means. – Giffyguy Aug 21 '09 at 05:27
  • 2
    When I said read only I meant the dependency property metadata cannot be overriden. You will get an exception when trying to call OverrideMetadata. If that is the case you can't do much I am afraid. – Igor Zevaka Aug 21 '09 at 05:57
  • Does it matter where you place this code ? For instance could i create a static contractor in some object in my wpf application and when compiling it will merge the meta data with the one from the framework with the default settings , or do i have to subclass the FrameworkElement witch i would like it to effect ? – eran otzap May 13 '14 at 09:57
  • You can check [this](https://stackoverflow.com/questions/7618402/how-to-override-metadata-for-a-dependency-property) SO question for the place you need to put the above code – Murat Aykanat Aug 20 '17 at 10:54