Josue Cc
Josue Cc

Reputation: 28

Bind Textbox Text with style from template to a viewmodel

I have some textbox whith style from a template like this

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Border Background="White" CornerRadius="8" x:Name="container">
                        <Grid>
                            <TextBox Background="White"
                                     FontFamily="Poppins" FontSize="11"
                                     VerticalAlignment="Center"
                                     Padding="5"
                                     Name="SearchBox"
                                     Foreground="Black"
                                     Margin="2"
                                     BorderThickness="0"
                                     Text="{TemplateBinding Text}"
                                    />

                            <TextBlock Text="{TemplateBinding Tag}" Name="Placeholder"
                                       FontSize="11" FontFamily="Poppins"
                                       Foreground="Gray"
                                       VerticalAlignment="Center"
                                       IsHitTestVisible="False"
                                       Grid.Column="1" Padding="5" Margin="6,0,0,0">

                                <TextBlock.Style>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Text, ElementName=SearchBox}" Value="">
                                                <Setter Property="Visibility" Value="Visible"></Setter>
                                            </DataTrigger>
                                        </Style.Triggers>
                                        <Setter Property="Visibility" Value="Hidden"></Setter>
                                    </Style>
                                </TextBlock.Style>
                            </TextBlock>
                        </Grid>

                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Background" Value="#E6E6E6" TargetName="container"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Just to show an placeholder. This works but something goes wrong when I try to bind property Text to a view model.

                        <TextBox Text="{Binding NombreCliente}" 
                         Style="{StaticResource SearchTextBox}"
                         Grid.Row="1"
                             Tag="Nombre"/>

I've done test and while the textbox have this style the binding always return null or "". I find in other ask that there's something whith binding parent and they solve whith this

  <TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, 
  UpdateSourceTrigger=PropertyChanged}"....

But if i bind text to a template parent, how do I bind to viewmodel?

Upvotes: 0

Views: 634

Answers (2)

EldHasp
EldHasp

Reputation: 7943

If this is a template for use in a TextBox, then you have created it incorrectly.
In fact, instead of giving the TextBox room to display the text, you have overlapped it on top with another TextBox that has nothing to do with the one this template will use.
TextBox to display text looks in its template for a ScrollViewer named PART_ContentHost.
And all the property settings of the TextBox must be moved to Setters outside the template.

Example template:

<Style TargetType="TextBox">
    <Setter Property="Background" Value="White"/>
    <Setter Property="FontFamily" Value="Poppins"/>
    <Setter Property="FontSize" Value="11"/>
    <Setter Property="Padding" Value="5"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Margin" Value="2"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border Background="{TemplateBinding Background}"
                        CornerRadius="8" x:Name="container"
                        Padding="{TemplateBinding Padding}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid>
                        <ScrollViewer x:Name="PART_ContentHost"
                                        Focusable="false"
                                        HorizontalScrollBarVisibility="Hidden"
                                        VerticalScrollBarVisibility="Hidden"/>

                        <TextBlock Text="{TemplateBinding Tag}" Name="Placeholder"
                                FontSize="11" FontFamily="Poppins"
                                Foreground="Gray"
                                VerticalAlignment="Center"
                                IsHitTestVisible="False"
                                Grid.Column="1" Padding="5" Margin="6,0,0,0">

                            <TextBlock.Style>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding Text, ElementName=SearchBox}" Value="">
                                            <Setter Property="Visibility" Value="Visible"></Setter>
                                        </DataTrigger>
                                    </Style.Triggers>
                                    <Setter Property="Visibility" Value="Hidden"/>
                                </Style>
                            </TextBlock.Style>
                        </TextBlock>
                    </Grid>

                </Border>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Background" Value="#E6E6E6" TargetName="container"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Upvotes: 1

mm8
mm8

Reputation: 169360

A template of a TextBox should not contain another TextBox control.

Replace it with a ScrollViewer and set the FontFamily and FontSize properties using Style setters:

<ControlTemplate TargetType="{x:Type TextBox}">
    <Border Background="White" CornerRadius="8" x:Name="container">
        <Grid>
            <ScrollViewer x:Name="PART_ContentHost" Margin="2" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>

            <TextBlock Text="{TemplateBinding Tag}" Name="Placeholder"
                                       FontSize="11" FontFamily="Poppins"
                                       Foreground="Gray"
                                       VerticalAlignment="Center"
                                       IsHitTestVisible="False"
                                       Grid.Column="1" Padding="5" Margin="6,0,0,0">

                <TextBlock.Style>
                    <Style TargetType="{x:Type TextBlock}">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Text, ElementName=SearchBox}" Value="">
                                <Setter Property="Visibility" Value="Visible"></Setter>
                            </DataTrigger>
                        </Style.Triggers>
                        <Setter Property="Visibility" Value="Hidden"></Setter>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </Grid>

    </Border>

    <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="#E6E6E6" TargetName="container"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Upvotes: 1

Related Questions