如何在 XAML 中绑定 UIElements?

How to bind UIElements in XAML?

我有一个class:

class LinkedTextBox: TextBox
{
    public TextBox TextBoxA { get; set; }
    public TextBox TextBoxB { get; set; }
}

假设我有两个文本框:

    <TextBox x:Name="txt1" />
    <TextBox x:Name="txt2" />

如何在 Xaml 上指定文本框?

我的测试:

(1)“"TextBox" 的 TypeConverter 不支持从字符串转换。

    <local:LinkedTextBox TextBoxA="txt1" TextBoxB="txt2" />

(2) “A 'Binding' 不能设置在类型 'LinkedTextBox' 的 'TextBoxA' 属性 上。A 'Binding' 可以只能在 DependencyObject 的 DependencyProperty 上设置。"

    <local:LinkedTextBox 
        TextBoxA="{Binding ElementName=txt1}"  
        TextBoxB="{Binding ElementName=txt2}"  
        />

我认为有一个显而易见的方法,但我不知道如何...

没错。您的第二个示例是正确的 XAML,但它失败了,因为 TextBoxATextBoxB 是错误的 属性。 Binding 的目标必须是 DependencyObjectDependencyProperty,就像罐头上写的那样。 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
}

但是你的意图是什么?你想达到什么目的? 很可能您可以通过以正常方式将现有属性彼此绑定来实现,而无需任何这些子类 monkeyshines。可能你想要一个 attached property,这是一种特殊类型的依赖 属性.

更新

OP 希望添加说明文本框之间关系的视觉元素。如果要添加视觉叠加层,WPF 的实现方式是编写 an Adorner。因此,您将编写某种具有 TextBoxATextBoxB 依赖属性的 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 的装饰器,而不仅仅是文本框。天空是极限!如果你能梦想它,你就可以装饰它!