-1

I have the following class, which "hosts" a dependency property, that is registered for all types of FrameWorkElement.

Here it is:

public class DPHost: DependencyObject
    {
        public static readonly DependencyProperty MyStringProperty = DependencyProperty.Register("MyString", typeof(String), typeof(FrameworkElement), new PropertyMetadata(OnMyStringChanged));

        public static String GetMyString(DependencyObject obj)
        {
            return (String)obj.GetValue(MyStringProperty);
        }

        public static void SetMyString(DependencyObject obj, String value)
        {
            obj.SetValue(MyStringProperty, value);
        }

        public String MyString
        {
            get { return (String)GetValue(MyStringProperty); }
            set { SetValue(MyStringProperty, value); }
        }


        private static void OnMyStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }
    }

This example code DOES WORK:

    <Border x:Name="_ErrorBorder" c:DPHost.MyString="ABC"/>

This example code DOES NOT WORK:

<ControlTemplate.Triggers>
    <Trigger SourceName="_ImageCircle" Property="IsEnabled" Value="True">
        <Setter TargetName="_ErrorBorder" Property="c:DPHost.MyString" Value="ABC"/>
    </Trigger>
</ControlTemplate.Triggers>

The code does compile, the given trigger works 100% properly, but when I use the above setter code for "_ErrorBorder", I get the error:

"System.Windows.Markup.XamlParseException occurred"

InnerException: HResult=-2147467261 Message=The value can not be null Parametername: property ParamName=property Source=PresentationFramework StackTrace: bei System.Windows.Setter.CheckValidProperty(DependencyProperty property) bei System.Windows.Baml2006.WpfSharedBamlSchemaContext.<>c.b__341_0(Object target, Object value) bei System.Windows.Baml2006.WpfKnownMemberInvoker.SetValue(Object instance, Object value) bei MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(XamlMember member, Object obj, Object value) bei MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value) InnerException:

I have tested to implement the "MyString" DP directly in a class of type Border, then it worked.

I think it is some kind of syntax error or a different behaviour of the DP system, when it comes to setters, where the DP is not directly hosted inside the user control.

Thank you for any hints or links or complete answers!

If you are curious what I want to achieve: I like to implement global and central DPs for all types of FrameWorkElement inside a UserControl library.




This is the answer/solution to this question: (big credit to ibebbs for taking the time to really help me)

Change the owner type from "FrameworkElement" to "DPHost" and let the class DPHost inherit from FrameworkElement.

public class DPHost:FrameworkElement
    {

        public static readonly DependencyProperty MyStringProperty = DependencyProperty.RegisterAttached("MyString", typeof(String), typeof(DPHost), new PropertyMetadata(OnMyStringChanged));


        public static String GetMyString(DependencyObject obj)
        {
            return (String)obj.GetValue(MyStringProperty);
        }

        public static void SetMyString(DependencyObject obj, String value)
        {
            obj.SetValue(MyStringProperty, value);
        }

        private static void OnMyStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }
    }

1. Now this WORKS:

<Border x:Name="_ErrorBorder"  c:DPHost.MyString="ABC"/>

2. Now this WORKS TOO (this was the error)

 <ControlTemplate.Triggers>
     <Trigger SourceName="_ImageCircle" Property="IsEnabled" Value="True">
        <Setter TargetName="_ErrorBorder"   Property="c:DPHost.MyString" Value="THE BORDER" />
        <Setter TargetName="_ImageCircle"   Property="c:DPHost.MyString" Value="THE CIRCLE"/>
     </Trigger>
  </ControlTemplate.Triggers>

3. Just a little explanation, what it is all about

I need different dependency properties for ALL types of FrameworkElement, without creating any new base classes. The goal is to implement a generic animation framework. So this "MyString" property was just an abstract example to help me, what I want to achieve.

Michael
  • 938
  • 1
  • 10
  • 34
  • You seem to be trying to implement an attached property. Why are you calling `DependencyProperty.Register()` instead of `DependencyProperty.RegisterAttached()`? Why is `DPHost` not a static class? Where would you have an instance of it? If this is all intentional, it seems that you've left some important pieces out of your question. Please provide a good [mcve] that reliably reproduces the problem. – Peter Duniho Sep 06 '16 at 02:13
  • Thank you, Peter, that's right. I have changed it to DependencyProperty.RegisterAttached() but the error stays the same. – Michael Sep 06 '16 at 02:17
  • Peter, I have made the class static now and changed it to DependencyProperty.RegisterAttached(). The first example still works, the second example also does not work with this new implementation. It is the same error. – Michael Sep 06 '16 at 02:26
  • **Please provide a good [mcve] that reliably reproduces the problem.** – Peter Duniho Sep 06 '16 at 02:31
  • I have added the Visual Studio error for more information. – Michael Sep 06 '16 at 02:31
  • Peter, you ask for a example. The example code is above in the question from the beginning. Please see: "This does work" and "This does not work" – Michael Sep 06 '16 at 02:32
  • Please read **[mcve]** again. Pay in particular close attention to the concept of **complete**. Also, please read **[ask]**, including visiting each of the pages at the links at the bottom of the page. Again, pay close attention to their explanations of what **complete** means and why it's important. – Peter Duniho Sep 06 '16 at 02:36
  • Peter, there is really nothing to add to this example. I have this one class DPHost, I use the DP in the first example. It works. I use it in the second example. It does not work. Should I upload a mini VS project somewhere? – Michael Sep 06 '16 at 02:42
  • I have added another example at the end of the question. I can not make any clearer. – Michael Sep 06 '16 at 03:18
  • Closed per OP's suggested duplicate target. – Peter Duniho Jan 30 '17 at 04:37

1 Answers1

1

Michael, looking it the code, it looks like you're actually trying to define an 'attached property' rather than a regular dependency property. I'm not 100% that this will solve the trigger/setter issue but can't hurt to try.

Also noted that the 'owner' of the dependency property in your code is 'FrameworkElement' when it should be 'DPHost'. This answer has additional info.

Community
  • 1
  • 1
ibebbs
  • 1,963
  • 2
  • 13
  • 20
  • Thank you, ibbes, but that did not help. The error occurs in this line of code: . The type Border has no MyString property directly. What makes me mad is, that I can set this property "normally" in XAML, but not in the setter of the control template. – Michael Sep 06 '16 at 11:53
  • Michael, I extended my answer. Should hopefully solve the problem. – ibebbs Sep 06 '16 at 12:03
  • OH MY GOD! THIS IS THE RIGHT HINT. I will extend my question with the answer. Thank you so much. – Michael Sep 06 '16 at 12:13
  • Thank you Ibebbs, I added the solution in the question. Thank you so much for taking your time to help me. – Michael Sep 06 '16 at 12:40