You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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>

实现方案

核心思路

直接修改背景色无法实现滑动效果,需要通过添加背景覆盖层+宽度动画来模拟:

  1. 在原border内部新增一个高亮用的Border,初始宽度为0,背景设为目标颜色,圆角与外层边框一致。
  2. 鼠标进入时,通过动画将高亮边框的宽度从0过渡到外层边框的实际宽度,实现从左到右的滑动覆盖。
  3. 鼠标离开时,反向动画将宽度恢复为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:54:22