如何在 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,但它失败了,因为 TextBoxA
和 TextBoxB
是错误的 属性。 Binding
的目标必须是 DependencyObject
的 DependencyProperty
,就像罐头上写的那样。 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。因此,您将编写某种具有 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
的装饰器,而不仅仅是文本框。天空是极限!如果你能梦想它,你就可以装饰它!
我有一个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,但它失败了,因为 TextBoxA
和 TextBoxB
是错误的 属性。 Binding
的目标必须是 DependencyObject
的 DependencyProperty
,就像罐头上写的那样。 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。因此,您将编写某种具有 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
的装饰器,而不仅仅是文本框。天空是极限!如果你能梦想它,你就可以装饰它!