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

WPF自定义ProgressBar样式后丢失循环动画功能求助

解决WPF ProgressBar循环模式(Indeterminate)样式失效问题

问题根源

你自定义的ProgressBar模板中,PART_Indicator只是一个静态填充的Rectangle,缺失了Indeterminate模式必需的动画逻辑。默认ProgressBar的循环效果依赖于动画控制视觉元素的偏移或渐变滚动,静态矩形自然无法呈现循环动效。

修复方案

方案一:复用标准循环动画逻辑,仅替换颜色

基于默认模板的动画框架修改,保留原生流动式循环效果,同时使用你自定义的颜色资源:

<Style TargetType="{x:Type ProgressBar}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Grid x:Name="TemplateRoot" SnapsToDevicePixels="true">
                    <!-- 背景轨道 -->
                    <Rectangle x:Name="PART_Track" Fill="{DynamicResource MyDimmedBrush}" />
                    <!-- 指示器容器 -->
                    <Decorator x:Name="PART_Indicator" HorizontalAlignment="Left">
                        <Grid x:Name="Foreground">
                            <!-- 非循环模式的静态指示器 -->
                            <Rectangle x:Name="Indicator" Fill="{DynamicResource MyBrush}" Margin="{TemplateBinding Padding}" />
                            <!-- 循环模式的动画遮罩层 -->
                            <Rectangle x:Name="Animation" Fill="{DynamicResource MyBrush}" Opacity="0.3">
                                <Rectangle.OpacityMask>
                                    <LinearGradientBrush StartPoint="-1,0" EndPoint="2,0">
                                        <GradientStop Color="#00FFFFFF" Offset="0" />
                                        <GradientStop Color="#FFFFFFFF" Offset="0.5" />
                                        <GradientStop Color="#00FFFFFF" Offset="1" />
                                    </LinearGradientBrush>
                                </Rectangle.OpacityMask>
                                <Rectangle.Triggers>
                                    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                                        <BeginStoryboard>
                                            <Storyboard RepeatBehavior="Forever">
                                                <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                                                 From="0" To="{Binding ActualWidth, ElementName=TemplateRoot}"
                                                                 Duration="0:0:1.5" />
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </EventTrigger>
                                </Rectangle.Triggers>
                                <Rectangle.RenderTransform>
                                    <TranslateTransform />
                                </Rectangle.RenderTransform>
                            </Rectangle>
                        </Grid>
                    </Decorator>
                </Grid>
                <!-- 状态切换触发器 -->
                <ControlTemplate.Triggers>
                    <Trigger Property="IsIndeterminate" Value="true">
                        <Setter TargetName="Indicator" Property="Visibility" Value="Collapsed" />
                    </Trigger>
                    <Trigger Property="IsIndeterminate" Value="false">
                        <Setter TargetName="Animation" Property="Visibility" Value="Collapsed" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

此方案在循环模式下会显示带渐变遮罩的滚动动画,完全匹配原生ProgressBar的流动体验,同时全程使用你定义的MyBrush和MyDimmedBrush。

方案二:自定义渐变滚动动画(简化版)

如果不需要复杂的遮罩效果,可直接给指示器的填充Brush添加滚动动画:

<Style TargetType="{x:Type ProgressBar}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ProgressBar}">
                <Grid x:Name="TemplateRoot" SnapsToDevicePixels="true">
                    <Rectangle x:Name="PART_Track" Fill="{DynamicResource MyDimmedBrush}" />
                    <Rectangle x:Name="PART_Indicator"
                               HorizontalAlignment="Left" 
                               Margin="{TemplateBinding Padding}">
                        <Rectangle.Style>
                            <Style TargetType="Rectangle">
                                <Setter Property="Fill" Value="{DynamicResource MyBrush}" />
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsIndeterminate, RelativeSource={RelativeSource TemplatedParent}}" Value="true">
                                        <Setter Property="Fill">
                                            <Setter.Value>
                                                <LinearGradientBrush StartPoint="-1,0" EndPoint="2,0">
                                                    <GradientStop Color="{DynamicResource MyBrush}" Offset="0" />
                                                    <GradientStop Color="{DynamicResource MyBrush}" Offset="0.4" />
                                                    <GradientStop Color="Transparent" Offset="0.6" />
                                                    <GradientStop Color="{DynamicResource MyBrush}" Offset="1" />
                                                    <LinearGradientBrush.Triggers>
                                                        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                                                            <BeginStoryboard>
                                                                <Storyboard RepeatBehavior="Forever">
                                                                    <DoubleAnimation Storyboard.TargetProperty="StartPoint.X"
                                                                                     From="-1" To="2" Duration="0:0:1.5" />
                                                                    <DoubleAnimation Storyboard.TargetProperty="EndPoint.X"
                                                                                     From="2" To="5" Duration="0:0:1.5" />
                                                                </Storyboard>
                                                            </BeginStoryboard>
                                                        </EventTrigger>
                                                    </LinearGradientBrush.Triggers>
                                                </LinearGradientBrush>
                                            </Setter.Value>
                                        </Setter>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Rectangle.Style>
                    </Rectangle>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

该方案在循环模式下,指示器的填充色会通过渐变滚动产生流动感,非循环模式则自动切换回静态填充。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:40:25