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
相关产品推荐
相关产品推荐

