WPF如何将Button点击事件传递至ContentTemplate?
如何在ContentTemplate中响应外部控件的事件并触发动画
可以将外部控件(如Button)的事件传递到ContentTemplate中触发动画,但你原来的写法不生效是有明确原因的,下面逐一说明并给出可行解决方案:
为什么直接在DataTemplate.Triggers绑定Button.Click不生效?
DataTemplate的EventTrigger默认监听的是模板内部元素的事件,而非外部控件的事件。你的代码里,DataTemplate.Triggers中的EventTrigger没有指定事件源,所以它会监听模板根元素(Grid)的Click事件,而不是外部Button的Click事件——点击Button时,事件不会触发Grid的Click,自然动画不会运行。
可行解决方案
方案1:通过RelativeSource指定事件源为Button
修改DataTemplate中的EventTrigger,明确指定事件源为外部的Button,这样就能监听Button的Click事件:
<Button Content="Hello"> <Button.ContentTemplate> <DataTemplate> <Grid x:Name="Grid"> <TextBlock Text="{Binding}"/> </Grid> <DataTemplate.Triggers> <EventTrigger RoutedEvent="Button.Click" Source="{RelativeSource AncestorType={x:Type Button}}"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="Grid" Storyboard.TargetProperty="Opacity" From="1" To=".5" Duration="0:0:0.500"/> </Storyboard> </BeginStoryboard> </EventTrigger> </DataTemplate.Triggers> </DataTemplate> </Button.ContentTemplate> </Button>
方案2:通过控件状态属性触发(适合点击这类状态关联事件)
如果是点击事件这类和控件状态相关的场景,可以监听Button的IsPressed属性,用DataTrigger触发动画,还能轻松添加状态恢复的动画:
<Button Content="Hello"> <Button.ContentTemplate> <DataTemplate> <Grid x:Name="Grid"> <TextBlock Text="{Binding}"/> </Grid> <DataTemplate.Triggers> <DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True"> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="Grid" Storyboard.TargetProperty="Opacity" From="1" To=".5" Duration="0:0:0.500"/> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> <!-- 点击松开后恢复透明度 --> <DataTrigger.ExitActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="Grid" Storyboard.TargetProperty="Opacity" From=".5" To="1" Duration="0:0:0.500"/> </Storyboard> </BeginStoryboard> </DataTrigger.ExitActions> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> </Button.ContentTemplate> </Button>
方案3:自定义事件的处理方式
如果是自定义路由事件,逻辑和内置事件一致:通过RelativeSource找到触发事件的控件,在EventTrigger中指定Source为该控件,同时监听你的自定义事件即可。如果自定义事件需要更复杂的传递逻辑,可以在自定义控件内部将事件路由到Content区域,再在DataTemplate中监听。
内容的提问来源于stack exchange,提问作者Developer333
相关产品推荐
相关产品推荐

