设置"托管"控件模板中的依赖项属性不起作用

时间:2016-09-06 01:51:48

标签: c# wpf dependency-properties target setter

我有以下课程,"主持人"一个依赖项属性,为所有类型的FrameWorkElement注册。

这是:

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)
        {

        }
    }

此示例代码 DOES WORK:

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

此示例代码 DOES NOT WORK

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

代码确实编译,给定的触发器100%正常工作,但当我使用上面的setter代码&#34; _ErrorBorder&#34;时,我收到错误:

&#34;发生了System.Windows.Markup.XamlParseException&#34;

的InnerException:        的HResult = -2147467261        Message =该值不能为null Parametername:属性        PARAMNAME =属性        来源= PresentationFramework        堆栈跟踪:             bei System.Windows.Setter.CheckValidProperty(DependencyProperty property)             bei System.Windows.Baml2006.WpfSharedBamlSchemaContext。&lt;&gt; c.b__341_0(对象目标,对象值)             bei System.Windows.Baml2006.WpfKnownMemberInvoker.SetValue(Object instance,Object value)             bei MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(XamlMember成员,对象obj,对象值)             bei MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst,XamlMember属性,Object value)        InnerException:

我已经测试过实现&#34; MyString&#34; DP直接在一个类型的Border中,然后它工作。

我认为这是某种语法错误或DP系统的不同行为,当涉及到设置者时,DP不直接托管在用户控件内。

感谢您提供任何提示或链接或完整答案!

如果您对我想要实现的目标感到好奇:我喜欢在UserControl库中为所有类型的FrameWorkElement实现全局和中央DP。

这是这个问题的答案/解决方案:(对于 ibebbs 的大功劳,因为它花时间真正帮助我)

从&#34; FrameworkElement&#34;更改所有者类型到&#34; DPHost&#34;让DPHost类继承自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。现在这个工作:

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

2。现在这个工作太糟糕了(这是错误的)

 <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。只是一点解释,它是什么

我需要所有类型 FrameworkElement 的不同依赖项属性,而不创建任何新的基类。目标是实现通用动画框架。所以这个&#34; MyString&#34;属性只是一个抽象的例子来帮助我,我想要实现的目标。

1 个答案:

答案 0 :(得分:1)

迈克尔,看着代码,看起来你实际上是在尝试定义'attached property'而不是常规的依赖属性。我不是百分之百,这将解决触发/设置器问题,但尝试不会伤害。

还要注意,代码中依赖项属性的“所有者”是“FrameworkElement”,它应该是“DPHost”。 This answer有其他信息。