[SOLVED] How to correctly use a UserControl in WPF?

Issue

I created this user control

<UserControl x:Class="POS1.Windows.Controles.txttransparente"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             Height="auto" Width=" auto"
             >


    <Border BorderBrush="Yellow" Background="Transparent" CornerRadius="10,10,10,10" Grid.Row="1"  Grid.Column="1" Grid.ColumnSpan="2">
        <TextBox  Name="txt1" Background="Transparent" BorderBrush="Black" BorderThickness="3" Text="Usuario" FontSize="20" FontWeight="ExtraBold" ></TextBox>
    </Border>


</UserControl>

When I add it to a Window,

<Controls:MetroWindow
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
        xmlns:Custom="http://modernwpf"  xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"  
    x:Class="POS1.MainWindow"
    xmlns:txt="clr-namespace:POS1.Windows.Controles"
        Title="MainWindow" Height="292" Width="535"  AllowsTransparency="True" WindowStyle="None" 
        >


    <Grid>

        <Grid.RowDefinitions >
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions >
            <ColumnDefinition Width="133*"/>
            <ColumnDefinition Width="134*"/>
            <ColumnDefinition Width="135*"/>
            <ColumnDefinition Width="133*"/>
        </Grid.ColumnDefinitions>
        <Border  Grid.ColumnSpan="4" Grid.RowSpan="7" CornerRadius="40,50,60,70">
            <Border.Background>
                <ImageBrush ImageSource="pack://siteoforigin:,,,/Resources/b.jpg"/>
            </Border.Background>

        </Border>
        <Border BorderBrush="Yellow" Background="Transparent" CornerRadius="10,10,10,10" Grid.Row="1"  Grid.Column="1" Grid.ColumnSpan="2">
            <TextBox   Background="Transparent" BorderBrush="Black" BorderThickness="3" Text="Usuario" FontSize="20" FontWeight="ExtraBold" ></TextBox>
        </Border>
        <TextBox Grid.Row="3"  Grid.Column="1" Grid.ColumnSpan="2" Text="Contraseña" FontSize="20" FontWeight="ExtraBold" ></TextBox>
        <Button Grid.Row="5"  Grid.Column="1"  Content="Aceptar" FontSize="12" FontWeight="ExtraBold"  ></Button>
        <Button Grid.Row="5"  Grid.Column="2"  Content="Olvidé contraseña" FontSize="12" FontWeight="ExtraBold"  ></Button>

        <txt:txttransparente Content=" Hola Mundo" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" ></txt:txttransparente>



    </Grid>
</Controls:MetroWindow>

as you see I could not modify the txt1.Text, so I have instead used Content="hola mundo"

enter image description here

However this sees it as above, but not as similar to the button usuario.

Solution

Without explicitly navigating the control’s visual tree, the elements in your UserControl need for you to implement mechanism to pass data from client code using your control to the elements contained within. A common strategy for doing this is to simply declare a property on your UserControl type itself, and then bind the appropriate member in the control’s tree to that property.

For example:

class txttransparente : UserControl
{
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text", typeof(string), typeof(txttransparente));

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

Then in your XAML for the UserControl:

<UserControl x:Class="POS1.Windows.Controles.txttransparente"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:POS1.Windows.Controles"
             mc:Ignorable="d" 
             Height="auto" Width=" auto">

    <Border BorderBrush="Yellow" Background="Transparent" CornerRadius="10,10,10,10"
            Grid.Row="1"  Grid.Column="1" Grid.ColumnSpan="2">
        <TextBox  Name="txt1" Background="Transparent" BorderBrush="Black"
                  BorderThickness="3"
                  Text="{Binding Text, 
RelativeSource={RelativeSource AncestorType={x:Type local:
txttransparente}}}"
                  FontSize="20"
                  FontWeight="ExtraBold"/>
    </Border>
</UserControl>

Note the change not only in the binding for the TextBox.Text property there, but also the addition of the xmlns:local declaration, so that the binding can find the parent UserControl object where the property exists.

These changes create the property, and connect it to the Text property of the control’s TextBox element.

Then finally, where you use the UserControl, you simply set the Text property (instead of Content):

<txt:txttransparente Text="Hola Mundo" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2"/>

Answered By – Peter Duniho

Answer Checked By – David Goodson (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *