WPF:绑定更改时如何触发EventTrigger(或动画)?

WPF:绑定更改时如何触发EventTrigger(或动画)?,wpf,data-binding,storyboard,eventtrigger,Wpf,Data Binding,Storyboard,Eventtrigger,我们有一个简单的动画,当选中和取消选中ToggleButton(展开ListView的高度,然后折叠ListView的高度)时运行。当以下XAML中的x:Name=“DetailsGrid”网格中的DataContext绑定发生更改时,如何触发的EventTrigger(或动画) 换句话说,每当“DetailsGrid”的绑定发生更改时,我们都希望触发“CommentsCollapse”情节提要,以确保ListView返回到其折叠状态 <Page xmlns="http://sche

我们有一个简单的动画,当选中和取消选中ToggleButton(展开ListView的高度,然后折叠ListView的高度)时运行。当以下XAML中的
x:Name=“DetailsGrid”
网格中的DataContext绑定发生更改时,如何触发
的EventTrigger(或动画)

换句话说,每当“DetailsGrid”的绑定发生更改时,我们都希望触发“CommentsCollapse”情节提要,以确保ListView返回到其折叠状态

<Page
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Width="800"
   Height="400">
   <Page.Resources>
      <Storyboard x:Key="CommentsExpand">
         <DoubleAnimationUsingKeyFrames
            BeginTime="00:00:00"
            Storyboard.TargetName="CommentsListView"
            Storyboard.TargetProperty="(FrameworkElement.Height)">
            <SplineDoubleKeyFrame KeyTime="00:00:00.200" Value="300"/>
         </DoubleAnimationUsingKeyFrames>
      </Storyboard>
      <Storyboard x:Key="CommentsCollapse">
         <DoubleAnimationUsingKeyFrames
            BeginTime="00:00:00"
            Storyboard.TargetName="CommentsListView"
            Storyboard.TargetProperty="(FrameworkElement.Height)">
            <SplineDoubleKeyFrame KeyTime="00:00:00.200" Value="75"/>
         </DoubleAnimationUsingKeyFrames>
      </Storyboard>
   </Page.Resources>
   <Page.Triggers>
      <EventTrigger RoutedEvent="ToggleButton.Checked" SourceName="CommentsToggleButton">
         <BeginStoryboard Storyboard="{StaticResource CommentsExpand}"/>
      </EventTrigger>
      <EventTrigger RoutedEvent="ToggleButton.Unchecked" SourceName="CommentsToggleButton">
         <BeginStoryboard Storyboard="{StaticResource CommentsCollapse}"/>
      </EventTrigger>
   </Page.Triggers>
   <Grid DataContext="{Binding Path=CurrentTask.Workflow.Invoice}" x:Name="DetailsGrid">
      <StackPanel Orientation="Horizontal">
         <Canvas Width="428">
            <GroupBox Width="422" Margin="5,0,0,0">
               <GroupBox.Header>
                  <StackPanel Orientation="Horizontal">
                     <ToggleButton
                        x:Name="CommentsToggleButton"
                        Width="20"
                        Height="10"
                        Margin="5,0,0,0">
                        <ToggleButton.Content>
                           <Rectangle
                              Width="5"
                              Height="5"
                              Fill="Red"/>
                        </ToggleButton.Content>
                     </ToggleButton>
                     <TextBlock Foreground="Blue" Text="Comments"/>
                  </StackPanel>
               </GroupBox.Header>
               <ListView
                  x:Name="CommentsListView"
                  Height="75"
                  ItemsSource="{Binding Path=Comments}">
                  <ListView.View>
                     <GridView>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=Date}" Header="Date"/>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="User"/>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=Description}" Header="Comment"/>
                     </GridView>
                  </ListView.View>
               </ListView>
            </GroupBox>
         </Canvas>
      </StackPanel>
   </Grid>
</Page>


我认为您不能通过纯Xaml来实现这一点,您必须在代码中实现这一点(或者更好的是,编写一个通用表达式行为,以便可以用Xaml来描述它)。查看依赖项属性的PropertyMetadata,看看如何钩住它的属性更改事件。

我也发现在XAML中这是不可能的。您需要DataContextChanged事件,它不是RoutedEvent,因此不能在EventTrigger中使用

但这似乎是可行的:

<Window x:Class="DatacontextChangedSpike.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Storyboard x:Key="ListViewExpands" AutoReverse="True" RepeatBehavior="2x">
            <DoubleAnimation Storyboard.TargetName="PulsingListView" Storyboard.TargetProperty="Height"
                            From="10" To="60"/>
        </Storyboard>
    </Window.Resources>
    <StackPanel>
        <ListView Name="PulsingListView" BorderThickness="2" BorderBrush="Black"
                  DataContextChanged="PulsingListView_DataContextChanged">
            <TextBlock>Listview</TextBlock>
        </ListView>
        <Button Click="Button_Click" >Change DataContext</Button>
    </StackPanel>
</Window>

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DatacontextChangedSpike
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            DataContext = new List<string>();
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            DataContext = new List<int>();
        }

        private void PulsingListView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var sb = (Storyboard)FindResource("ListViewExpands");
            sb.Begin();
        }
    }
}

控件
更改数据上下文
使用制度;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Media.Animation;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间DatacontextChangedSpike
{
公共部分类Window1:Window
{
公共窗口1()
{
DataContext=新列表();
初始化组件();
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
DataContext=新列表();
}
私有void PulsingListView\u DataContextChanged(对象发送方,DependencyPropertyChangedEventArgs e)
{
var sb=(故事板)FindResource(“ListViewExpands”);
某人开始做某事;
}
}
}

如果在更改DataContext时可以将ViewModel属性设置为true或false,则可以从DataTrigger(EnterAction和ExitAction)触发情节提要。因此,DataTrigger将基于您的新Bool属性

@Paul,你有什么资源(链接)可以给我指出正确的方向吗?@Jobi-最初我们做了类似的事情,关于:使用ViewModel处理触发器,但是我们最终还是按照Dabblernl的建议使用了DataContextChanged事件,因为它将UI逻辑保留在UI中而不在模型中。@Dabblernl-我们最初尝试过这个,但希望有一个纯粹的XAML解决方案。谢谢