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

如何自定义WPF不确定状态进度条的动画速度与指示条宽度

实现方案

你之前的写法无法生效,核心原因是Animation元素是ProgressBar默认控件模板的内部元素,在外层Grid定义VisualStateManager根本访问不到模板内部的目标,自然覆盖不了默认动画。
要实现调慢不确定态动画速度、加宽内部指示条的需求,直接重写ProgressBar的控件模板即可,不需要额外写后台逻辑调用VSM。

核心调整点

  • 动画速度:修改Indeterminate状态下Storyboard的总时长,时长越长动画播放速度越慢
  • 指示条宽度:直接修改模板内滑动指示条元素的最小宽度,数值越大指示条越宽

完整可用代码

把下面的自定义样式放在窗口资源中,给ProgressBar引用该样式即可:

<Window x:Class="IndeterminateProgressBarTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="100" Width="700">
    <Window.Resources>
        <Style x:Key="SlowWideProgressBarStyle" TargetType="ProgressBar">
            <Setter Property="Foreground" Value="#0078D4"/>
            <Setter Property="Background" Value="#F0F0F0"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ProgressBar">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Determinate">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateIndicator" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <DoubleAnimation Storyboard.TargetName="DeterminateIndicator" Storyboard.TargetProperty="Width"
                                                             To="{TemplateBinding Value}" Duration="0:0:0.2"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Indeterminate">
                                        <Storyboard RepeatBehavior="Forever">
                                            <!-- 总时长设为4秒,比默认2秒慢一倍,需要更慢就把KeyTime改大 -->
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateIndicator" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="-350"/>
                                                <EasingDoubleKeyFrame KeyTime="0:0:4" Value="650"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <!-- 进度条轨道 -->
                            <Border Background="{TemplateBinding Background}" CornerRadius="4"/>
                            <!-- 确定状态进度指示 -->
                            <Border x:Name="DeterminateIndicator" HorizontalAlignment="Left" Background="{TemplateBinding Foreground}" CornerRadius="4"/>
                            <!-- 不确定状态滑动指示条 MinWidth设为350,比默认180宽近一倍,需要更宽就改这个值 -->
                            <Border x:Name="IndeterminateIndicator" HorizontalAlignment="Left" Background="{TemplateBinding Foreground}" CornerRadius="4"
                                    MinWidth="350" Height="{TemplateBinding Height}">
                                <Border.RenderTransform>
                                    <TranslateTransform X="-350"/>
                                </Border.RenderTransform>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <ProgressBar Width="600" Height="25" IsIndeterminate="True" Style="{StaticResource SlowWideProgressBarStyle}"/>
    </Grid>
</Window>

参数自定义说明

  • 调整动画速度:修改Indeterminate状态下第二个EasingDoubleKeyFrame的KeyTime值,比如改成0:0:6动画速度会更慢
  • 调整指示条宽度:修改IndeterminateIndicator的MinWidth值,数值越大滑动的指示条越宽,注意同步修改动画起始X值和初始TranslateTransform的X值,保证动画首尾衔接自然
  • 不需要保留确定状态功能的话,可以直接删掉模板里的DeterminateIndicator相关代码,进一步简化模板

内容的提问来源于stack exchange,提问作者Wellwoah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:01:06