简体   繁体   English

如何在XAML中绑定UIElements?

[英]How to bind UIElements in XAML?

I have a class: 我有一节课:

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

Say I have two Textboxes: 说我有两个文本框:

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

How do I to specify that TextBoxes on my Xaml? 如何在我的Xaml上指定TextBoxes?

My tests: 我的测试:

(1) " The TypeConverter for "TextBox" does not support converting from a string. " (1)“ TypeBox的TypeConverter不支持从字符串转换。

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

(2) " A 'Binding' cannot be set on the 'TextBoxA' property of type 'LinkedTextBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject. " (2)“ A'Binding'不能在'LinkedTextBox'类型的'TextBoxA'属性上设置。'Binding'只能在DependencyObject的DependencyProperty上设置。

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

I think that there is an obvious way to do, but I don't know how to... 我认为有一种明显的方法可做,但我不知道如何......

Right. 对。 Your second example is correct XAML, but it fails because TextBoxA and TextBoxB are the wrong kind of property. 你的第二个例子是正确的XAML,但它失败了,因为TextBoxATextBoxB属于错误的属性。 The target of a Binding must be a DependencyProperty of a DependencyObject , like it says on the tin. Binding的目标必须是DependencyPropertyDependencyObject ,就像在锡上所说的那样。 TextBox is already a DependencyObject and you're subclassing it, so that part's taken care of. TextBox已经是一个DependencyObject ,你正在对它进行子类化,因此该部分需要处理。 And defining a DependencyProperty is trivial. 定义DependencyProperty是微不足道的。

You would define TextBoxA like this, and TextBoxB likewise: 您需要定义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
}

But what is your intent here? 但你的意图是什么? What are you trying to accomplish? 你想达到什么目的? It's very likely that you can do it by binding existing properties to each other in a normal way, without any of these subclass monkeyshines. 你很可能通过以正常方式将现有属性彼此绑定来实现它,而没有任何这些子类monkeyshines。 Possibly you'd want an attached property , which is a specialized type of dependency property. 可能你想要一个附加属性 ,这是一种特殊类型的依赖属性。

UPDATE UPDATE

OP wants to add visual elements illustrating relationships among the text boxes. OP希望添加说明文本框之间关系的视觉元素。 If you want to add a visual overlay, the WPF Way to Do That is to write an Adorner . 如果你想添加一个视觉叠加层,那么WPF的方法就是写一个Adorner So you'd write some kind of TextBoxLinkingAdorner with TextBoxA and TextBoxB dependency properties, and apply that to the main text box, which depending on your requirements might not even have to be a subclass. 因此,您将使用TextBoxATextBoxB依赖项属性编写某种TextBoxLinkingAdorner ,并将其应用于主文本框,这取决于您的要求甚至可能不必是子类。

Your dependency properties might need to do some work when their values change; 您的依赖属性可能需要在其值更改时执行一些操作; if so, they'd look more like this, assuming an Adorner subclass named TextBoxLinkerAdorner : 如果是这样,假设一个名为TextBoxLinkerAdornerAdorner子类,它们看起来更像这样:

    #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

If all you're looking at on the text boxes is their size and location, you might write an adorner that links arbitrary UIElements , not just text boxes. 如果您在文本框中查看的是它们的大小和位置,您可以编写一个链接任意UIElements而不仅仅是文本框的装饰器。 The sky's the limit! 天空是极限! If you can dream it, you can adorn it! 如果你能梦想它,你可以装饰它!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM