如何在ControlTemplate内的VisualStateManager中动画化模板控件属性?
解决WPF自定义圆形进度条模板中动画化控件Value属性的问题
核心问题分析
你尝试在ControlTemplate的VisualState中直接绑定TemplatedParent的Value属性做动画时出现报错,原因是Storyboard的Target属性不支持通过RelativeSource绑定指定目标,WPF无法解析这种绑定方式找到对应的FrameworkElement。
可行解决方案
给ControlTemplate的根容器(Grid)添加命名,通过该容器间接绑定到TemplatedParent的Value属性,具体实现如下:
修改后的完整样式代码
<Style x:Key="{x:Type control:CircularProgressIndicator}" TargetType="{x:Type control:CircularProgressIndicator}" BasedOn="{StaticResource {x:Type ProgressBar}}"> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type control:CircularProgressIndicator}"> <!-- 给根Grid添加命名 --> <Grid x:Name="Root"> <Path x:Name="PART_Path" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Stroke="{TemplateBinding Foreground}" StrokeThickness="{TemplateBinding StrokeThickness}"> <Path.Data> <PathGeometry> <PathGeometry.Figures> <PathFigureCollection> <PathFigure x:Name="PART_Figure"> <PathFigure.Segments> <PathSegmentCollection> <ArcSegment x:Name="PART_ArcSegment" /> </PathSegmentCollection> </PathFigure.Segments> </PathFigure> </PathFigureCollection> </PathGeometry.Figures> </PathGeometry> </Path.Data> </Path> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Determinate" /> <VisualState x:Name="Indeterminate"> <Storyboard> <!-- 通过Root容器间接绑定到TemplatedParent的Value属性 --> <DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="(FrameworkElement.TemplatedParent).Value" From="0" To="100" RepeatBehavior="Forever" /> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="VerticalContentAlignment" Value="Center" /> </Style>
原理说明
- 模板内的命名元素
Root是FrameworkElement,WPF可以通过Storyboard.TargetName正确定位它 - 通过
(FrameworkElement.TemplatedParent).Value路径,能从Root容器反向找到应用该模板的CircularProgressIndicator控件,进而访问其Value属性 - 这种方式避开了直接绑定TemplatedParent作为Target的限制,符合WPF的动画目标解析规则
内容的提问来源于stack exchange,提问作者Oliver Giesen
相关产品推荐
相关产品推荐

