I want to display a line on the bottom of a TextBox when its hovered over

93 Views Asked by At

So basically I want to achieve a hover-effect and that effect would be a line would appear on the bottom of a textbox, the width of that line must be half the actual width of the TextBox.

If possible, I would like an animation, perhaps a ColorAnimation that would gradually change its color from transparent to solid. I also wanted to specify that my TextBox is a watermarked TextBox.

An example of what I want to achieve is this: EXAMPLE

<Style TargetType="{x:Type local:TextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TextBox}">
                <DockPanel HorizontalAlignment="Stretch">
                    <Border CornerRadius="10" BorderBrush="{StaticResource BackgroundColor}" BorderThickness="1" Background="{StaticResource BackgroundColor}">
                        <Grid Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}">
                            <TextBox Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}" VerticalAlignment="Center" Foreground="{StaticResource TextColor}" Background="{StaticResource BackgroundColor}" Padding="10" HorizontalAlignment="Left" x:Name="SearchTermTextBox" Margin="5" BorderThickness="0"/>
                                <TextBlock IsHitTestVisible="False" Text="Enter Search Term Here" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="20,0,0,0" Foreground="{StaticResource TextColor}" Background="{StaticResource BackgroundColor}">
                                    <TextBlock.Style>
                                        <Style TargetType="{x:Type TextBlock}">
                                            <Setter Property="Visibility" Value="Collapsed"/>
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding Text, ElementName=SearchTermTextBox}" Value="">
                                                    <Setter Property="Visibility" Value="Visible"/>
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </TextBlock.Style>
                                </TextBlock>
                        </Grid>         
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
2

There are 2 best solutions below

0
Emperor Eto On BEST ANSWER

TextBox is a Control so it can be re-templated like any other. The trick is to ensure that there is a child element named PART_ContentHost - which is ordinarily a ScrollViewer - which will be used by the control to render the editable text. (See the WPF Default Styles and Templates documentation for TextBox for more detail).

Here is a simple example that will display an underline on hover with a 0.25 second fade in/out and will take up 50% of the TextBox's width (thanks to some Grid column logic). You should be able to tweak it further to get the look/behavior you want. And don't forget you can always subclass TextBox to add more DependencyPropertys for additional granularity over the appearance.

<Style x:Key="ResponsiveTextBoxStyle"
       TargetType="TextBox"
       BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="BorderBrush"
            Value="Blue" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="Underline"
                                                     Storyboard.TargetProperty="(Border.Opacity)"
                                                     To="0"
                                                     Duration="0:00:00.25" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="Underline"
                                                     Storyboard.TargetProperty="(Border.Opacity)"
                                                     To="1"
                                                     Duration="0:00:00.25" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ScrollViewer Margin="0"
                                  Grid.Row="0"
                                  Grid.ColumnSpan="4"
                                  x:Name="PART_ContentHost" />
                    <Border x:Name="Underline"
                            Grid.Row="1"
                            Opacity="0"
                            BorderThickness="1"
                            Height="2"
                            Grid.Column="1"
                            Grid.ColumnSpan="2"
                            BorderBrush="{TemplateBinding BorderBrush}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
0
Bayan On

you can use MaterialDesign's FieldsLineUp item :

 <TextBox
 x:Name="NameTextBox"      
 md:HintAssist.Hint="Username" Width="180"
 md:TextFieldAssist.UnderlineBrush="LimeGreen"

Style="{StaticResource MaterialDesignFloatingHintTextBox}"> this shows Underline when clicking on TextBox. for hovering, you may need a trigger,

<Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="underline" Property="Visibility" Value="Visible"/> </Trigger>