我正在尝试在自定义WPF DependencyObject 中为DependencyProperty实现值继承,而且我的表现非常糟糕:(
我想做什么:
我有两个类 T1 和 T2 ,它们都有DependencyProperty IntTest ,默认为0.T1应该是T2的根,就像一个Window是它包含的TextBox的逻辑根/父。
因此,当我没有明确地设置 T2.IntTest 的值时,它应该提供 T1.IntTest 的值(就像例如TextBox.FlowDirection通常提供的那样)父窗口的FlowDirection)。
我做了什么:
我创建了两个类T1和T2,派生自FrameworkElement,以便将 FrameworkPropertyMetadata 与 FrameworkPropertyMetadataOptions.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;
答案 0 :(得分: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
派生的,因此ContentControl
和ItemsControl
所提供的遏制带来的任何好处都不具备儿童(分别为单个和多个)的概念英寸