8

I have a several TextBoxes with Labels in my code which are implemented with the following XAML:

<DockPanel HorizontalAlignment="Right">
    <TextBlock Foreground="Black" Padding="0,0,10,0">Serial Number:</TextBlock>
    <TextBox Width="150" IsReadOnly="True" BorderBrush="Gainsboro" Height="20"></TextBox>
</DockPanel>

I can reduce some of the copied code by doing something like:

<DockPanel HorizontalAlignment="Right">
    <TextBlock Style="{StaticResource CstmTextBoxLbl}">Serial Number:</TextBlock>
    <TextBox Style="{StaticResource CstmTextBox}"></TextBox>
</DockPanel>

but it is still somewhat lengthy. Is it possible to do something like:

<controls:CstmTextBox Style="{StaticResource CstmTextBox}" LabelText="Serial Number:" Text=""/>

Where the CstmTextBox would implement the whatever XAML is needed to get the same visual effect once, and I could access both the TextBlock text and the TextBox text in the code. Such as

CstmTextBox textbox;
textbox.LabelText = "Serial Number:";
String some_text = textbox.Text;

textbox.Text = "....";
1
  • 3
    Create a UserControl. Commented Jul 22, 2015 at 16:46

2 Answers 2

5

Add a UserControl to your solution, and copy the XAML you want to reuse inside.

If you set x:Name to the controls inside your UserControl...

<UserControl ... >
    <DockPanel HorizontalAlignment="Right">
        <TextBlock x:Name="SerialNumberTextBlock" Style="{StaticResource CstmTextBoxLbl}">Serial Number:</TextBlock>
        <TextBox x:Name="SerialNumberTextBox" Style="{StaticResource CstmTextBox}"></TextBox>
    </DockPanel>
</UserControl>

... you'll be able to access them from outside (code-behind) like this:

CstmTextBox textbox;
textbox.SerialNumberTextBlock.Text = "Serial Number:";
String some_text = textbox.SerialNumberTextBox.Text;

textbox.SerialNumberTextBox.Text = "....";

But it's even better if you create DependencyProperties for the properties you want to expose. You define those properties in the code-behind of your UserControl:

public string Text
{
    get
    {
        return (string)GetValue(TextProperty);
    }
    set
    {
        SetValue (TextProperty, value);
    }
}

public static readonly DependencyProperty TextProperty = 
    DependencyProperty.Register("Text", typeof(string), typeof (CstmTextBox));

Then bind those properties to the controls inside your UserControl:

<UserControl x:Name="Root" ... >
    <DockPanel HorizontalAlignment="Right">
        <TextBlock x:Name="SerialNumberTextBlock" Style="{StaticResource CstmTextBoxLbl}"
                   Text="{Binding LabelText, ElementName=Root}" />
        <TextBox x:Name="SerialNumberTextBox" Style="{StaticResource CstmTextBox}"
                 Text="{Binding Text, ElementName=Root, Mode=TwoWay}" />
    </DockPanel>
</UserControl>

That way you can set the properties directly from outside, be it code-behind, XAML or Binding.

Sign up to request clarification or add additional context in comments.

Comments

4

A UserControl or a CustomControl serves your needs. This is the code for a CustomControl.

C#:

public class CstmTextBox : Control
{
    public string LabelText
    {
        get
        {
            return (string)GetValue (LabelTextProperty);
        }
        set
        {
            SetValue (LabelTextProperty, value);
        }
    }

    public static readonly DependencyProperty LabelTextProperty =
        DependencyProperty.Register ("LabelText", typeof (string), typeof (CstmTextBox), new PropertyMetadata (string.Empty));

    public string Text
    {
        get
        {
            return (string)GetValue (TextProperty);
        }
        set
        {
            SetValue (TextProperty, value);
        }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register ("Text", typeof (string), typeof (CstmTextBox), new PropertyMetadata (string.Empty));
}

XAML:

    <Style TargetType="{x:Type controls:CstmTextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:CstmTextBox}">
                    <DockPanel HorizontalAlignment="Right">
                        <TextBlock Foreground="Black" Padding="0,0,10,0" Text="{TemplateBinding LabelText}"/>
                        <TextBox Width="150" IsReadOnly="True" BorderBrush="Gainsboro" Height="20" Text="{TemplateBinding Text}"/>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Add the style to your resources and use the new control:

    <controls:CstmTextBox LabelText="abcde" Text="1234"/>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.