WPF Composite Controls

c#, data-binding, wpf

Solution

Binding is really the way to go:

XAML:

<UserControl x:Class="testapp.LabelTextBox "
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300" x:Name="This">
<DockPanel>
    <TextBlock DockPanel.Dock="Left" TextAlignment="Right" Width="70" Name="label" Text="{Binding Label, ElementName=This}"  />
    <TextBlock Text=": " DockPanel.Dock="Left" />
    <TextBox Name="textBox" Text="{Binding Text, ElementName=This}" />
</DockPanel>

Code Behind:

    public partial class LabelTextBox : UserControl
{
    public LabelTextBox()
    {
        InitializeComponent();
        Label = "Label";
        Text = "Text";
    }
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabelTextBox), new FrameworkPropertyMetadata(LabelPropertyChangedCallback));
    private static void LabelPropertyChangedCallback(DependencyObject controlInstance, DependencyPropertyChangedEventArgs args)
    {
    }
    public string Label
    {
        get { return (string) GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LabelTextBox), new FrameworkPropertyMetadata(TextPropertyChangedCallback));
    private static void TextPropertyChangedCallback(DependencyObject controlInstance, DependencyPropertyChangedEventArgs args)
    {
    }
    public string Text
    {
        get { return (string) GetValue(TextProperty); }
        set { SetValue(LabelTextBox.TextProperty, value); }
    }
}

Problem

I'm trying to create a reusable UserControl in WPF that has a Label and a TextBox. I want to add properties to my UserControl to bubble up the Text fields of both child controls up to the parent for easy binding. I read that I need to a little bit of hocus pocus by adding owners to DependencyProperties. Here is my code now. It seems close but not quite right. Any ideas? Here is the Xaml: ``` <UserControl x:Class="MAAD.AircraftExit.Visual.LabelTextBox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="20" Width="300"> <DockPanel> <TextBlock Text="{Binding Path=Label, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" DockPanel.Dock="Left" TextAlignment="Right" Width="122" /> <TextBlock Text=": " DockPanel.Dock="Left"/> <TextBox Text="{Binding Path=Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" /> </DockPanel> </UserControl> ``` And the code behind: ``` public partial class LabelTextBox : UserControl { public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabelTextBox)); public string Label { get { return (string)GetValue(LabelProperty); } set { SetValue(LabelProperty, value); } } public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LabelTextBox)); public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(LabelTextBox.TextProperty, value); } } public LabelTextBox() { InitializeComponent(); ClearValue(HeightProperty); ClearValue(WidthProperty); } } ``` Edit: Here is the final working code. I switched over to relative source binding.

Original source