I have my own UserControl, a LabeledTextBox
which is the combination of a Label
and a..well, TextBox
. This Control has two properties: Caption
which will be bound to the caption of the Label
, and Value
which will be bound to the Text
of the TextBox
.
Code:
public class LabeledTextBox : Control
{
static LabeledTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(LabeledTextBox), new FrameworkPropertyMetadata(typeof(LabeledTextBox)));
}
public string Caption
{
get { return (string)GetValue(CaptionProperty); }
set { SetValue(CaptionProperty, value); }
}
// Using a DependencyProperty as the backing store for Caption. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption", typeof(string), typeof(LabeledTextBox), new UIPropertyMetadata(""));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string), typeof(LabeledTextBox), new UIPropertyMetadata(""));
}
XAML:
<Style TargetType="{x:Type local:LabeledTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:LabeledTextBox}">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{TemplateBinding Caption}" />
<TextBox Name="Box" Margin="3,0,3,3" Grid.Row="1" Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage:
<uc:LabeledTextBox Caption="Code:" Value="{Binding ExpenseCode}" />
Initially I thought I had found my answer here: WPF TemplateBinding vs RelativeSource TemplatedParent
That details the difference between TemplateBinding
and RelativeSource TemplatedParent
. I've changed my code accordingly, but it still feels like I'm missing a step. The OneWay binding does work, my textbox is bound to the Value property, but changes do not register.
How do I get this to work?
Change the mode here.
<uc:LabeledTextBox Caption="Code:" Value="{Binding ExpenseCode,Mode=TwoWay}" />
it worked at my end
Just in case anybody has this problem:
Another approach (maybe more elegant) would be to declare the dependency property of the usercontrol in a way so that it defaults to two way binding (e.g. as the framework TextBox does by default).
This can be achieved as follows (taken from the answer of this Stackoverflow question):
public DependencyProperty SomeProperty =
DependencyProperty.Register("Some", typeof(bool), typeof(Window1),
new FrameworkPropertyMetadata(default(bool),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
The key here is using FrameworkPropertyMetadata
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With