如何为ItemsControl内部元素绑定上层按钮作为动画触发源?
问题原因
你遇到的名称查找失败是因为DataTemplate属于独立的XAML名称范围,模板内部的SourceName只能查找同个模板内的控件,无法访问到ItemsControl外定义的PlayButton。
解决方案
方案1:快速修复(仅修改一行XAML)
直接用x:Reference突破名称范围限制,替换原来的SourceName即可:
<!-- 把原来的EventTrigger行替换成下面的 --> <EventTrigger RoutedEvent="Button.Click" Source="{x:Reference PlayButton}">
如果要加停止功能,再新增一个对应Stop按钮的触发器即可,记得给原有BeginStoryboard加x:Name="CircleAnimBegin"关联停止操作:
<EventTrigger RoutedEvent="Button.Click" Source="{x:Reference StopButton}"> <StopStoryboard BeginStoryboardName="CircleAnimBegin"/> </EventTrigger>
方案2:严格遵循MVVM(推荐)
这种方式完全移除视图的硬编码依赖,用ViewModel属性驱动动画:
1. 修改ParentViewModel
新增播放状态属性和操作命令:
public class ParentViewModel : BindableBase { private bool _isPlaying; public bool IsPlaying { get => _isPlaying; set => SetProperty(ref _isPlaying, value); } public DelegateCommand PlayCommand { get; } public DelegateCommand StopCommand { get; } private List<MyCircle> myItemsModel; public List<MyCircle> MyItemsModel { get => myItemsModel; set => SetProperty(ref myItemsModel, value); } public ParentViewModel() { PlayCommand = new DelegateCommand(() => IsPlaying = true); StopCommand = new DelegateCommand(() => IsPlaying = false); // 保留原有实例化MyItemsModel的逻辑 } }
2. 修改XAML绑定
首先替换按钮的Click事件为命令绑定:
<Button Content="Play" Grid.Row="0" Grid.Column="1" Command="{Binding PlayCommand}"/> <Button Content="Stop" Grid.Row="1" Grid.Column="1" Command="{Binding StopCommand}"/>
然后把DataTemplate里的EventTrigger换成DataTrigger,通过RelativeSource绑定到父级ViewModel的IsPlaying属性:
<Path Fill="Red" x:Name="ClockwiseBobbinsPath"> <Path.Data> <EllipseGeometry x:Name="MyCircle" RadiusX="5" RadiusY="5"/> </Path.Data> <Path.Style> <Style TargetType="Path"> <Style.Triggers> <DataTrigger Binding="{Binding DataContext.IsPlaying, RelativeSource={RelativeSource AncestorType=ItemsControl}}" Value="True"> <DataTrigger.EnterActions> <BeginStoryboard x:Name="CircleAnimBegin"> <Storyboard> <PointAnimationUsingPath Storyboard.TargetProperty="Data.Center" Duration="0:0:10" RepeatBehavior="Forever"> <PointAnimationUsingPath.PathGeometry> <PathGeometry Figures="{Binding AnimationPath}" PresentationOptions:Freeze="True" /> </PointAnimationUsingPath.PathGeometry> </PointAnimationUsingPath> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> <DataTrigger.ExitActions> <StopStoryboard BeginStoryboardName="CircleAnimBegin"/> </DataTrigger.ExitActions> </DataTrigger> </Style.Triggers> </Style> </Path.Style> </Path>
这里移除了Storyboard.TargetName,改为直接绑定Data.Center属性,避免额外的名称查找问题。
内容的提问来源于stack exchange,提问作者Yose
相关产品推荐
相关产品推荐

