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?
My tests:
(1) " The TypeConverter for "TextBox" does not support converting from a string. "
<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. "
<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. The target of a Binding
must be a DependencyProperty
of a DependencyObject
, like it says on the tin. TextBox
is already a DependencyObject
and you're subclassing it, so that part's taken care of. And defining a DependencyProperty
is trivial.
You would define TextBoxA
like this, and TextBoxB
likewise:
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. Possibly you'd want an attached property , which is a specialized type of dependency property.
OP wants to add visual elements illustrating relationships among the text boxes. If you want to add a visual overlay, the WPF Way to Do That is to write an 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.
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
:
#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. The sky's the limit! If you can dream it, you can adorn it!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.