0

我正在尝试在自定义 WPF DependencyObject 中为 DependencyProperty 实现值继承,但我失败了:(

我想做的事:

我有两个类T1T2都有一个 DependencyProperty IntTest,默认为 0。T1 应该是 T2 的根,就像 Window 是它包含的 TextBox 的逻辑根/父级一样。

因此,当我没有明确设置T2.IntTest的值时,它应该提供T1.IntTest的值(就像 TextBox.FlowDirection 通常提供父窗口的 F​​lowDirection 一样)。

我做了什么:

我创建了两个类 T1 和 T2,从 FrameworkElement 派生,以便将FrameworkPropertyMetadataFrameworkPropertyMetadataOptions.Inherits一起使用。我还读到,为了使用值继承,您必须将 DependencyProperty 设计为 AttachedProperty。

目前,当我为根 T1 赋值时,子 T2 的 DP-Getter 不会返回它。

我究竟做错了什么???

这是两个类:

// Root class
public class T1 : FrameworkElement
{
    // Definition of an Attached Dependency Property 
    public static readonly DependencyProperty IntTestProperty = DependencyProperty.RegisterAttached("IntTest", typeof(int), typeof(T1), 
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.Inherits));

    // Static getter for Attached Property
    public static int GetIntTest(DependencyObject target)
    {
        return (int)target.GetValue(IntTestProperty);
    }

    // Static setter for Attached Property
    public static void SetIntTest(DependencyObject target, int value)
    {
        target.SetValue(IntTestProperty, value);
    }

    // CLR Property Wrapper
    public int IntTest
    {
        get {  return GetIntTest(this); }
        set { SetIntTest(this, value); }
    }
}


// Child class - should inherit the DependenyProperty value of the root class
public class T2 : FrameworkElement
{
    public static readonly DependencyProperty IntTestProperty = T1.IntTestProperty.AddOwner(typeof(T2),
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.Inherits));

    public int IntTest
    {
        get { return (int)GetValue(IntTestProperty); }
        set { SetValue(IntTestProperty, value); }
    }
}

这是试用它的代码:

        T1 t1 = new T1();
        T2 t2 = new T2();

        // Set the DependencyProperty of the root
        t1.IntTest = 123;

        // Do I have to build a logical tree here? If yes, how?

        // Since the DependencyProperty of the child was not set explicitly, 
        // it should provide the value of the base class, i.e. 123. 
        // But this does not work: i remains 0   :((
        int i = t2.IntTest;    
4

1 回答 1

0

附加属性的关键属性是它可以(通常是)在与设置它的对象不同的对象上声明。在这种情况下,您已经声明了您需要的所有内容,T1但您应该停在那里(尽管摆脱IntTest属性包装器 - AP 使用 Get/Set 方法代替)。您也可以IntTest在其他一些辅助类上声明。无论您在何处声明它,都可以将其设置在任何 DependencyObject.

// set on the declaring type
T1.SetIntTest(t1, 123);
// set on your other type
T1.SetIntTest(t2, 456);
// set on any other framework type
Button button = new Button();
T1.SetIntTest(button, 789);

您似乎正在努力解决的另一部分是设置您的树。继承作为逻辑层次结构的一部分工作,因此为了从另一个实例继承值,继承对象需要是原始对象的逻辑子对象。由于您是从基础派生出来的,因此您FrameworkElement没有获得任何包含内置子概念(分别为单个和多个)的收容所带来的好处。ContentControlItemsControl

于 2014-05-15T14:17:59.663 回答