如何在WPF中实现TextBox边框背景从左到右的滑动动画?
WPF实现边框背景从左到右滑动的动画效果
我是WPF新手,想要实现边框背景从左到右滑动的动画效果(背景色从左侧逐步覆盖整个边框的过渡)。目前我找到一段颜色切换的代码,但只能直接替换颜色,达不到滑动的效果:
<EventTrigger RoutedEvent="TextBox.MouseEnter"> <BeginStoryboard> <Storyboard SlipBehavior="Slip"> <ColorAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.Color" To="Blue" Duration="00:00:00.2" /> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="TextBox.MouseLeave"> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.Color" To="WhiteSmoke" Duration="00:00:00.2" /> </Storyboard> </BeginStoryboard> </EventTrigger>
我只会用Blend做对象移动动画,不知道怎么实现这种颜色滑动效果,以下是我当前的TextBox完整样式代码:
<Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}"> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/> <Setter Property="FontSize" Value="8"/> <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/> <Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="AllowDrop" Value="true"/> <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TextBox}"> <Grid> <Border x:Name="border" Background="White" BorderBrush="#FF7D8683" CornerRadius="5" BorderThickness="0"/> <ScrollViewer x:Name="PART_ContentHost" Margin="5,0,0,0" VerticalAlignment="Center" /> <Label Margin="5,0,0,0" x:Name="WaterMarkLabel" Content="{TemplateBinding Tag}" VerticalAlignment="Center" Visibility="Collapsed" Foreground="Gray" FontFamily="Arial"/> </Grid> <ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="Text" Value=""/> </MultiTrigger.Conditions> <Setter Property="Visibility" TargetName="WaterMarkLabel" Value="Visible"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Foreground" Value="DimGray"/> </Trigger> <EventTrigger RoutedEvent="TextBox.MouseEnter"> <BeginStoryboard> <Storyboard SlipBehavior="Slip"> <ColorAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.Color" To="Blue" Duration="00:00:00.2" /> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="TextBox.MouseLeave"> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.Color" To="WhiteSmoke" Duration="00:00:00.2" /> </Storyboard> </BeginStoryboard> </EventTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/> <Condition Property="IsSelectionActive" Value="false"/> </MultiTrigger.Conditions> <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/> </MultiTrigger> </Style.Triggers> </Style>
实现方案
核心思路
直接修改背景色无法实现滑动效果,需要通过添加背景覆盖层+宽度动画来模拟:
- 在原
border内部新增一个高亮用的Border,初始宽度为0,背景设为目标颜色,圆角与外层边框一致。 - 鼠标进入时,通过动画将高亮边框的宽度从0过渡到外层边框的实际宽度,实现从左到右的滑动覆盖。
- 鼠标离开时,反向动画将宽度恢复为0,实现滑出效果。
修改后的完整样式代码
<Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}"> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/> <Setter Property="FontSize" Value="8"/> <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/> <Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="AllowDrop" Value="true"/> <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TextBox}"> <Grid> <!-- 原背景边框 --> <Border x:Name="border" Background="White" BorderBrush="#FF7D8683" CornerRadius="5" BorderThickness="0"> <!-- 新增的高亮滑动层 --> <Border x:Name="highlightBorder" Background="Blue" CornerRadius="5" Width="0" HorizontalAlignment="Left"/> </Border> <ScrollViewer x:Name="PART_ContentHost" Margin="5,0,0,0" VerticalAlignment="Center" /> <Label Margin="5,0,0,0" x:Name="WaterMarkLabel" Content="{TemplateBinding Tag}" VerticalAlignment="Center" Visibility="Collapsed" Foreground="Gray" FontFamily="Arial"/> </Grid> <ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="Text" Value=""/> </MultiTrigger.Conditions> <Setter Property="Visibility" TargetName="WaterMarkLabel" Value="Visible"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Foreground" Value="DimGray"/> </Trigger> <!-- 鼠标进入:滑动显示高亮 --> <EventTrigger RoutedEvent="TextBox.MouseEnter"> <BeginStoryboard> <Storyboard SlipBehavior="Slip"> <DoubleAnimation Storyboard.TargetName="highlightBorder" Storyboard.TargetProperty="Width" To="{Binding ActualWidth, ElementName=border}" Duration="00:00:00.2"/> </Storyboard> </BeginStoryboard> </EventTrigger> <!-- 鼠标离开:滑动隐藏高亮 --> <EventTrigger RoutedEvent="TextBox.MouseLeave"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="highlightBorder" Storyboard.TargetProperty="Width" To="0" Duration="00:00:00.2"/> </Storyboard> </BeginStoryboard> </EventTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/> <Condition Property="IsSelectionActive" Value="false"/> </MultiTrigger.Conditions> <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/> </MultiTrigger> </Style.Triggers> </Style>
说明
- 高亮层
highlightBorder设置HorizontalAlignment="Left",确保从左侧开始扩展。 - 动画绑定
border的ActualWidth,保证高亮层能完全覆盖原边框。 - 如果需要反向滑动(从右到左),只需将
highlightBorder的HorizontalAlignment改为Right即可。
内容的提问来源于stack exchange,提问作者TimGriffendor
相关产品推荐
相关产品推荐

