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>
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 DependencyProperty
s 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>