【问题标题】:How to bind UIElements in XAML?如何在 XAML 中绑定 UIElements?
【发布时间】:2016-03-24 16:11:58
【问题描述】:

我有一堂课:

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) "不能在'LinkedTextBox' 类型的'TextBoxA' 属性上设置'Binding'。'Binding' 只能在 DependencyObject 的 DependencyProperty 上设置。"

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

我认为有一个明显的方法可以做,但我不知道如何......

【问题讨论】:

    标签: c# wpf xaml data-binding dependency-properties


    【解决方案1】:

    没错。您的第二个示例是正确的 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 的装饰器,而不仅仅是文本框。天空是极限!如果你能梦想它,你就可以装饰它!

    【讨论】:

    • 我将在视觉上“链接”文本框(实际上是画线),改变两者的视觉效果,可能会改变位置,然后使用两者中的文本,在 LinkedTextBox 中处理和呈现结果。我知道通常的方法是直接绑定属性,但是我需要处理很多属性,而且当我可以直接绑定主 UIElement 时,我认为绑定十几个属性真的很糟糕。我现在将阅读有关附加属性的信息,谢谢!
    • @ClickOk Ahhh,现在我知道你从哪里来了。您可能想看看Adorners,这是(除其他外)“在 UIElement 上叠加视觉装饰”的 WPFish 方式。我认为 AdornerLayer 将属于 TextBoxes 的父级。
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多