没错。您的第二个示例是正确的 XAML,但它失败了,因为 TextBoxA 和 TextBoxB 是错误的属性类型。 Binding 的目标必须是 DependencyProperty 的 DependencyObject,就像它在锡上所说的那样。 TextBox 已经是 DependencyObject 并且您正在对它进行子类化,因此该部分已得到处理。并且定义一个DependencyProperty 是微不足道的。
你可以像这样定义TextBoxA,同样定义TextBoxB:
public class LinkedTextBox : TextBox
{
#region TextBoxA Property
public TextBox TextBoxA
{
get { return (TextBox)GetValue(TextBoxAProperty); }
set { SetValue(TextBoxAProperty, value); }
}
// Careful with the parameters you pass to Register() here.
public static readonly DependencyProperty TextBoxAProperty =
DependencyProperty.Register("TextBoxA", typeof(TextBox), typeof(LinkedTextBox),
new PropertyMetadata(null));
#endregion TextBoxA Property
}
但是你的意图是什么?你想达到什么目的? 您很可能可以通过以正常方式将现有属性相互绑定来做到这一点,而无需任何这些子类猴子。可能你想要一个attached property,它是一种特殊类型的依赖属性。
更新
OP 希望添加视觉元素来说明文本框之间的关系。如果要添加视觉覆盖,WPF 的做法是写an Adorner。因此,您将编写某种带有 TextBoxA 和 TextBoxB 依赖属性的 TextBoxLinkingAdorner,并将其应用于主文本框,根据您的要求,它甚至可能不必是子类。
当它们的值改变时,你的依赖属性可能需要做一些工作;如果是这样,它们看起来更像这样,假设有一个名为 TextBoxLinkerAdorner 的 Adorner 子类:
#region TextBoxA Property
public TextBox TextBoxA
{
get { return (TextBox)GetValue(TextBoxAProperty); }
set { SetValue(TextBoxAProperty, value); }
}
public static readonly DependencyProperty TextBoxAProperty =
DependencyProperty.Register("TextBoxA", typeof(TextBox),
typeof(TextBoxLinkerAdorner),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
TextBoxA_PropertyChanged)
{ DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
protected static void TextBoxA_PropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var obj = d as TextBoxLinkerAdorner;
}
#endregion TextBoxA Property
如果您在文本框上看到的只是它们的大小和位置,您可能会编写一个链接任意UIElements 的装饰器,而不仅仅是文本框。天空是极限!如果你能梦想它,你就可以装饰它!